diff --git a/README.md b/README.md index 73eadafb..a2201a7b 100644 --- a/README.md +++ b/README.md @@ -16,16 +16,7 @@ See the [installation section](https://sobolevn.github.io/git-secret/#installati ## Status -This project is still under development. Current objectives: - -- add `trust-model` parameter to `git-secret-hide` -- translate manuals for popular languages -- autocomplete for `zsh` plugin -- extra tests -- precompiled distribution for `RPM`, add dependencies for `.deb` package -- integrate [`shellcheck`](https://github.com/koalaman/shellcheck) for code style tests -- create `CONTRIBUTING.md` with development process explained -- сygwin support (?) +This project is still under development. See [https://github.com/sobolevn/git-secret/milestones](milestones) for the refence. ## Testing diff --git a/man/man1/git-secret-add.1 b/man/man1/git-secret-add.1 index d5a3cc4a..313253bc 100644 --- a/man/man1/git-secret-add.1 +++ b/man/man1/git-secret-add.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "GIT\-SECRET\-ADD" "1" "February 2016" "" "" +.TH "GIT\-SECRET\-ADD" "1" "May 2016" "" "" . .SH "NAME" \fBgit\-secret\-add\fR \- starts to track added files\. @@ -10,7 +10,7 @@ . .nf -git secret add \.\.\. +git secret add [\-i] \.\.\. . .fi . @@ -27,6 +27,7 @@ It is not recommened to add filenames directly into the \fB\.gitsecret/paths/map . .nf +\-i \- auto adds given files to the `\.gitignore` if they are unignored at the moment\. \-h \- shows this help\. . .fi diff --git a/man/man1/git-secret-changes.1 b/man/man1/git-secret-changes.1 new file mode 100644 index 00000000..eee5f776 --- /dev/null +++ b/man/man1/git-secret-changes.1 @@ -0,0 +1,31 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "GIT\-SECRET\-CHANGES" "1" "May 2016" "" "" +. +.SH "NAME" +\fBgit\-secret\-changes\fR \- view diff of the hidden files\. +. +.SH "SYNOPSIS" +. +.nf + +git secret changes [\-h] [\-d dir] [\-p password] \.\.\. +. +.fi +. +.SH "DESCRIPTION" +\fBgit\-secret\-changes\fR \- shows changes between the current version of hidden files and the ones already commited\. +. +.SH "OPTIONS" +. +.nf + +\-d \- specifies `\-\-homedir` option for the `gpg`, basically use this option if your store your keys in a custom location\. +\-p \- specifies password for noinput mode, adds `\-\-passphrase` option for `gpg`\. +\-h \- shows help\. +. +.fi +. +.SH "SEE ALSO" +git\-secret\-add(1), git\-secret\-tell(1), git\-secret\-hide(1), git\-secret\-reveal(1) diff --git a/man/man1/git-secret-changes.1.ronn b/man/man1/git-secret-changes.1.ronn new file mode 100644 index 00000000..2aa1b36b --- /dev/null +++ b/man/man1/git-secret-changes.1.ronn @@ -0,0 +1,22 @@ +git-secret-changes - view diff of the hidden files. +=================================================== + +## SYNOPSIS + + git secret changes [-h] [-d dir] [-p password] ... + + +## DESCRIPTION +`git-secret-changes` - shows changes between the current version of hidden files and the ones already commited. + + +## OPTIONS + + -d - specifies `--homedir` option for the `gpg`, basically use this option if your store your keys in a custom location. + -p - specifies password for noinput mode, adds `--passphrase` option for `gpg`. + -h - shows help. + + +## SEE ALSO + +git-secret-add(1), git-secret-tell(1), git-secret-hide(1), git-secret-reveal(1) diff --git a/man/man1/git-secret-reveal.1 b/man/man1/git-secret-reveal.1 index 7f8956ab..1125954f 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" "March 2016" "" "" +.TH "GIT\-SECRET\-REVEAL" "1" "May 2016" "" "" . .SH "NAME" \fBgit\-secret\-reveal\fR \- decrypts all added files\. @@ -10,7 +10,7 @@ . .nf -git secret reveal [\-d dir] [\-p password] +git secret reveal [\-f] [\-d dir] [\-p password] . .fi . @@ -21,6 +21,7 @@ git secret reveal [\-d dir] [\-p password] . .nf +\-f \- forces to overwrite exisiting files without prompt\. \-d \- specifies `\-\-homedir` option for the `gpg`, basically use this option if your store your keys in a custom location\. \-p \- specifies password for noinput mode, adds `\-\-passphrase` option for `gpg`\. \-h \- shows help\. diff --git a/man/man1/git-secret-reveal.1.ronn b/man/man1/git-secret-reveal.1.ronn index 3408768e..0c7c2bdf 100644 --- a/man/man1/git-secret-reveal.1.ronn +++ b/man/man1/git-secret-reveal.1.ronn @@ -3,7 +3,7 @@ git-secret-reveal - decrypts all added files. ## SYNOPSIS - git secret reveal [-d dir] [-p password] + git secret reveal [-f] [-d dir] [-p password] ## DESCRIPTION @@ -12,6 +12,7 @@ git-secret-reveal - decrypts all added files. ## OPTIONS + -f - forces to overwrite exisiting files without prompt. -d - specifies `--homedir` option for the `gpg`, basically use this option if your store your keys in a custom location. -p - specifies password for noinput mode, adds `--passphrase` option for `gpg`. -h - shows help. diff --git a/man/man7/git-secret.7 b/man/man7/git-secret.7 index 28db63f7..e7e87031 100644 --- a/man/man7/git-secret.7 +++ b/man/man7/git-secret.7 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "GIT\-SECRET" "7" "March 2016" "" "" +.TH "GIT\-SECRET" "7" "May 2016" "" "" . .SH "NAME" \fBgit\-secret\fR @@ -17,6 +17,9 @@ .IP "3." 4 \fIUsage\fR . +.IP "4." 4 +\fIConfiguration\fR +. .IP "" 0 . .SH "Intro" @@ -69,29 +72,38 @@ There are several ways to install \fBgit\-secret\fR: \fBBrew\fR . .IP "1." 4 -Run \fBbrew install sobolevn/tap/git\-secret\fR +Run \fBbrew install git\-secret\fR\. That will do\. Also, there are two options: +. +.IP "2." 4 +\fB\-\-without\-gpg\fR to build without \fBgpg\fR support +. +.IP "3." 4 +\fB\-\-HEAD\fR to install \fBHEAD\fR version +. +.IP "4." 4 +Note, that we have migrated from \fBtap\fR to the official \fBbrew\fR repo . .IP "" 0 . .P -\fB\fBantigen\fR plugin (or any other \fBoh\-my\-zsh\fR\-styled plugin\-systems)\fR +\fBManual\fR . .IP "1." 4 -Add line \fBantigen bundle sobolevn/git\-secret\fR to your \fB\.zshrc\fR +Clone the repository first: \fBgit clone https://github\.com/sobolevn/git\-secret\.git git\-secret\fR . .IP "2." 4 -Run \fBsource ~/\.zshrc\fR or reopen the terminal +Run \fBPREFIX="/usr/local" make install\fR, note that you can install to any prefix in your \fBPATH\fR . .IP "" 0 . .P -\fB\fBmake install\fR\fR +\fB\fBantigen\fR plugin (or any other \fBoh\-my\-zsh\fR\-styled plugin\-systems)\fR . .IP "1." 4 -Download the latest realease here \fIhttps://github\.com/sobolevn/git\-secret/releases\fR +Add line \fBantigen bundle sobolevn/git\-secret\fR to your \fB\.zshrc\fR . .IP "2." 4 -Unpack and run \fBmake install PREFIX="your/installation/path"\fR, note that this command may require \fBsudo\fR +Run \fBsource ~/\.zshrc\fR or reopen the terminal . .IP "" 0 . @@ -164,3 +176,18 @@ Reencypt the files, now they will be able to decrypt them with their secret key\ . .P Note, that it is possible to add yourself to the system without decrypting existing files\. It will be possible to decrypt them after reencrypting them with the new keyring\. So, if you don\'t want unexpected keys added, make sure to configure some server\-side security policy with the \fBpre\-receive\fR hook\. +. +.SH "Configuration" +You can configure several things to suit your workflow better\. To do so, just set the required variable to the value you need\. This can be done in your shell environment file or with the each \fBgit\-secret\fR command\. +. +.P +These settings are available to be changed: +. +.IP "\(bu" 4 +\fB$SECRETS_GPG_COMMAND\fR \- sets the \fBgpg\fR alternatives, defaults to \fBgpg\fR\. It can be changed to \fBgpg\fR, \fBgpg2\fR, \fBpgp\fR, \fB/usr/local/gpg\fR or any other value\. After doing so rerun tests to be sure, that it won\'t break anything\. Tested to be working with: \fBgpg\fR, \fBgpg2\fR\. +. +.IP "\(bu" 4 +\fB$SECRETS_EXTENSION\fR \- sets the secret files extension, defaults to \fB\.secret\fR\. It can be changed to any valid file extension\. +. +.IP "" 0 + diff --git a/man/man7/git-secret.7.ronn b/man/man7/git-secret.7.ronn index a027d8f6..1f685c4f 100644 --- a/man/man7/git-secret.7.ronn +++ b/man/man7/git-secret.7.ronn @@ -42,7 +42,10 @@ There are several ways to install `git-secret`: **Brew** -1. Run `brew install sobolevn/tap/git-secret` +1. Run `brew install git-secret`. That will do. Also, there are two options: + * `--without-gpg` to build without `gpg` support + * `--HEAD` to install `HEAD` version +2. Note, that we have migrated from `tap` to the official `brew` repo **Manual** diff --git a/src/_utils/_git_secret_tools.sh b/src/_utils/_git_secret_tools.sh index 4542621b..99c8c7e9 100644 --- a/src/_utils/_git_secret_tools.sh +++ b/src/_utils/_git_secret_tools.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -GITSECRET_VERSION="0.1.2" +GITSECRET_VERSION="0.2.0" # Global variables: WORKING_DIRECTORY="$PWD" @@ -85,7 +85,8 @@ function _file_has_line { function _delete_line { - _os_based __delete_line $@ + local escaped_path=$(echo "$1" | sed -e 's/[\/&]/\\&/g') + sed -i.bak "/$escaped_path/d" "$2" } @@ -115,6 +116,7 @@ function _unique_filename { # Manuals: + function _show_manual_for { local function_name="$1" man "git-secret-${function_name}" @@ -189,3 +191,37 @@ function _get_recepients { local result=$($GPGLOCAL --list-public-keys --with-colon | sed -n 's/.*<\(.*\)>.*/-r\1/p') echo "$result" } + + +function _decrypt { + # required: + local filename="$1" + + # optional: + local write_to_file=${2:-1} # can be 0 or 1 + local force=${3:-0} # can be 0 or 1 + local homedir=${4:-""} + local passphrase=${5:-""} + + local encrypted_filename=$(_get_encrypted_filename "$filename") + + local base="$SECRETS_GPG_COMMAND --use-agent -q --decrypt" + + if [[ "$write_to_file" -eq 1 ]]; then + base="$base -o "${filename}"" + fi + + if [[ "$force" -eq 1 ]]; then + base="$base --yes" + fi + + if [[ ! -z "$homedir" ]]; then + base="$base --homedir=$homedir" + fi + + if [[ ! -z "$passphrase" ]]; then + echo "$passphrase" | $base --batch --yes --no-tty --passphrase-fd 0 "$encrypted_filename" + else + $base "$encrypted_filename" + fi +} diff --git a/src/_utils/_git_secret_tools_linux.sh b/src/_utils/_git_secret_tools_linux.sh index 4ec683ed..514eb069 100644 --- a/src/_utils/_git_secret_tools_linux.sh +++ b/src/_utils/_git_secret_tools_linux.sh @@ -6,11 +6,6 @@ function __replace_in_file_linux { } -function __delete_line_linux { - sed -i.bak "/$1/d" "$2" -} - - function __temp_file_linux { local filename=$(mktemp) echo "$filename" diff --git a/src/_utils/_git_secret_tools_osx.sh b/src/_utils/_git_secret_tools_osx.sh index 06aaaa9a..7dcc23a2 100644 --- a/src/_utils/_git_secret_tools_osx.sh +++ b/src/_utils/_git_secret_tools_osx.sh @@ -6,11 +6,6 @@ function __replace_in_file_osx { } -function __delete_line_osx { - sed -i.bak "/$1/d" "$2" -} - - function __temp_file_osx { : "${TMPDIR:=/tmp}" local filename=$(mktemp -t _gitsecrets_XXX ) diff --git a/src/commands/git_secret_changes.sh b/src/commands/git_secret_changes.sh new file mode 100644 index 00000000..27b0405a --- /dev/null +++ b/src/commands/git_secret_changes.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +function changes { + OPTIND=1 + + while getopts "hd:p:" opt; do + case "$opt" in + h) _show_manual_for "changes";; + + p) passphrase=$OPTARG;; + + d) homedir=$OPTARG;; + esac + done + + shift $((OPTIND-1)) + [ "$1" = "--" ] && shift + + local filenames="$1" + if [[ -z "$filenames" ]]; then + # Checking if no filenames are passed, show diff for all files. + filenames=$(git secret list) + fi + + local previous_commit=$(git rev-parse HEAD) + + for filename in "$filenames"; do + # Meta information: + local encrypted_filename=$(_get_encrypted_filename "$filename") + local last_encrypted=$(git show "${previous_commit}:${encrypted_filename}") + + # Now we have all the data required: + local decrypted=$(_decrypt "$filename" "0" "0" "$homedir" "$passphrase") + local content=$(cat "$filename") + + local diff_result=$(diff <(echo "$decrypted") <(echo "$content")) + echo "changes in ${filename}: ${diff_result}" + done +} diff --git a/src/commands/git_secret_list.sh b/src/commands/git_secret_list.sh index 8dd6154b..7e7ff0ab 100644 --- a/src/commands/git_secret_list.sh +++ b/src/commands/git_secret_list.sh @@ -16,7 +16,7 @@ function list { _user_required if [[ ! -s "$SECRETS_DIR_PATHS_MAPPING" ]]; then - exit 1 + _abort "$SECRETS_DIR_PATHS_MAPPING is missing." fi while read line; do diff --git a/src/commands/git_secret_reveal.sh b/src/commands/git_secret_reveal.sh index 6143a0eb..2b1d2452 100644 --- a/src/commands/git_secret_reveal.sh +++ b/src/commands/git_secret_reveal.sh @@ -6,11 +6,14 @@ function reveal { OPTIND=1 local homedir="" local passphrase="" + local force=0 - while getopts "hd:p:" opt; do + while getopts "hfd:p:" opt; do case "$opt" in h) _show_manual_for "reveal";; + f) force=1;; + p) passphrase=$OPTARG;; d) homedir=$OPTARG;; @@ -24,18 +27,8 @@ function reveal { local counter=0 while read line; do - local encrypted_filename=$(_get_encrypted_filename "$line") - - local base="$SECRETS_GPG_COMMAND --use-agent -q --decrypt" - if [[ ! -z "$homedir" ]]; then - base="$base --homedir=$homedir" - fi - - if [[ ! -z "$passphrase" ]]; then - echo "$passphrase" | $base --batch --yes --no-tty --passphrase-fd 0 -o "$line" "$encrypted_filename" - else - $base -o "$line" "$encrypted_filename" - fi + # the parameters are: filename, force, homedir, passphrase + _decrypt "$line" "1" "$force" "$homedir" "$passphrase" counter=$((counter+1)) done < "$SECRETS_DIR_PATHS_MAPPING" diff --git a/tests/_test_base.bash b/tests/_test_base.bash index ddf1a052..f62b85c5 100644 --- a/tests/_test_base.bash +++ b/tests/_test_base.bash @@ -14,7 +14,6 @@ TEST_SECRETS_DIR="$BATS_TMPDIR/$SECRETS_DIR" TEST_SECRETS_DIR_PATHS_MAPPING="$BATS_TMPDIR/$SECRETS_DIR_PATHS_MAPPING" TEST_GPG_HOMEDIR="$PWD" -# TEST_TEMP_FILE="$BATS_TMPDIR/test_temp" # GPG-based stuff: : ${SECRETS_GPG_COMMAND:="gpg"} @@ -22,6 +21,7 @@ GPGTEST="$SECRETS_GPG_COMMAND --homedir=$TEST_GPG_HOMEDIR --no-permission-warnin # Personal data: + TEST_DEFAULT_USER="user1" function test_user_password { @@ -34,7 +34,6 @@ function test_user_email { } - # GPG: function _get_gpg_fingerprint_by_email { @@ -103,6 +102,7 @@ function uninstall_fixture_full_key { # Git: + function git_set_config_email { git config --local user.email "$1" } @@ -113,12 +113,22 @@ function git_restore_default_email { } +function git_commit { + git_set_config_email "$1" + git config --local user.name "Your Name" + + git add --all + git commit -m "$2" +} + + function remove_git_repository { rm -rf ".git" } # Git Secret: + function set_state_git { git init > /dev/null 2>&1 } diff --git a/tests/test_changes.bats b/tests/test_changes.bats new file mode 100644 index 00000000..1782d58e --- /dev/null +++ b/tests/test_changes.bats @@ -0,0 +1,60 @@ +#!/usr/bin/env bats + +load _test_base + +FILE_TO_HIDE="file_to_hide" +FILE_CONTENTS="hidden content юникод" + +FINGERPRINT="" + + +function setup { + FINGERPRINT=$(install_fixture_full_key "$TEST_DEFAULT_USER") + + 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_hide +} + + +function teardown { + uninstall_fixture_full_key "$TEST_DEFAULT_USER" "$FINGERPRINT" + unset_current_state + rm -f "$FILE_TO_HIDE" +} + + +@test "run 'changes' without previous commit" { + local password=$(test_user_password "$TEST_DEFAULT_USER") + local new_content="new content" + echo "$new_content" >> "$FILE_TO_HIDE" + + run git secret changes -d "$TEST_GPG_HOMEDIR" -p "$password" + [ "$status" -eq 0 ] + + # Testing that output has both filename and changes: + [[ "$output" == *"$FILE_TO_HIDE"* ]] + [[ "$output" == *"$new_content"* ]] +} + + +@test "run 'changes' without changes" { + local password=$(test_user_password "$TEST_DEFAULT_USER") + run git secret changes -d "$TEST_GPG_HOMEDIR" -p "$password" + [ "$status" -eq 0 ] +} + + +@test "run 'changes' with commit" { + git_commit "$(test_user_email $TEST_DEFAULT_USER)" 'initial' + local password=$(test_user_password "$TEST_DEFAULT_USER") + + echo "new content" >> "$FILE_TO_HIDE" + + run git secret changes -d "$TEST_GPG_HOMEDIR" -p "$password" + [ "$status" -eq 0 ] + [[ "$output" == *"$FILE_TO_HIDE"* ]] + [[ "$output" == *"$new_content"* ]] +} diff --git a/tests/test_remove.bats b/tests/test_remove.bats index 66c9b1f7..b54cd823 100644 --- a/tests/test_remove.bats +++ b/tests/test_remove.bats @@ -5,6 +5,11 @@ load _test_base FIRST_FILE="file_to_hide1" SECOND_FILE="file_to_hide2" +# There was a bug with `sed` an slashes: +# see https://github.com/sobolevn/git-secret/issues/23 +FOLDER="somedir" +FILE_IN_FOLDER="${FOLDER}/file_to_hide3" + function setup { install_fixture_full_key "$TEST_DEFAULT_USER" @@ -12,8 +17,8 @@ function setup { set_state_git set_state_secret_init set_state_secret_tell "$TEST_DEFAULT_USER" - set_state_secret_add "$FIRST_FILE" "$FIRST_FILE" - set_state_secret_add "$SECOND_FILE" "$SECOND_FILE" + set_state_secret_add "$FIRST_FILE" "somecontent" + set_state_secret_add "$SECOND_FILE" "somecontent2" } @@ -41,6 +46,22 @@ function teardown { } +@test "run 'remove' with slashes in filename" { + mkdir -p "$FOLDER" + set_state_secret_add "$FILE_IN_FOLDER" "somecontent3" + git secret hide + + run git secret remove "$FILE_IN_FOLDER" + [ "$status" -eq 0 ] + + local mapping_contains=$(grep "$FILE_IN_FOLDER" "$SECRETS_DIR_PATHS_MAPPING"; echo $?) + [ "$mapping_contains" -eq 1 ] + + local enctypted_file=$(_get_encrypted_filename $FILE_IN_FOLDER) + [ -f "$enctypted_file" ] +} + + @test "run 'remove -c'" { git secret hide diff --git a/tests/test_reveal.bats b/tests/test_reveal.bats index c04b0034..32dde2e7 100644 --- a/tests/test_reveal.bats +++ b/tests/test_reveal.bats @@ -42,6 +42,17 @@ function teardown { } +@test "run 'reveal' with '-f'" { + rm -f "$FILE_TO_HIDE" + + local password=$(test_user_password "$TEST_DEFAULT_USER") + run git secret reveal -f -d "$TEST_GPG_HOMEDIR" -p "$password" + + [ "$status" -eq 0 ] + [ -f "$FILE_TO_HIDE" ] +} + + @test "run 'reveal' with wrong password" { rm -f "$FILE_TO_HIDE" diff --git a/tests/test_tell.bats b/tests/test_tell.bats index d9e52167..da5e1804 100644 --- a/tests/test_tell.bats +++ b/tests/test_tell.bats @@ -4,7 +4,7 @@ load _test_base function setup { - install_fixture_key $TEST_DEFAULT_USER + install_fixture_key "$TEST_DEFAULT_USER" set_state_git set_state_secret_init } diff --git a/utils/post-commit.sh b/utils/post-commit.sh index fedc1858..e07d0543 100755 --- a/utils/post-commit.sh +++ b/utils/post-commit.sh @@ -4,7 +4,7 @@ set -e BRANCH_NAME=$(git branch | grep '*' | sed 's/* //') -if [[ "$BRANCH_NAME" == 'develop' ]]; then +if [[ "$BRANCH_NAME" == 'master' ]]; then # Build new web documentation: make build-gh-pages fi