pashage

Yet Another Opinionated Re-engineering of the Unix Password Store
git clone https://git.instinctive.eu/pashage.git
Log | Files | Refs | README | LICENSE

commit 1df6eb9701996fc71576f53272f9b8534603d871
parent b9ac582d07c6c85dca72b83693338b4b6313391d
Author: Natasha Kerensikova <natgh@instinctive.eu>
Date:   Fri,  8 Nov 2024 17:53:11 +0000

Re-encryption decision in init command is controlled by flags
Diffstat:
MREADME.md | 3+++
Mspec/pashage_extra_spec.sh | 65++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mspec/usage_spec.sh | 123++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/pashage.sh | 23++++++++++++++++++++++-
4 files changed, 199 insertions(+), 15 deletions(-)

diff --git a/README.md b/README.md @@ -73,6 +73,9 @@ passwords. - The commands `copy` and `move` have new flags to control re-encryption (always, never, ask for each file). +- The `init` command has new flags to control re-encryption (never or +ask for each file). + - The new `gitconfig` command configures an existing store repository to decrypt before `diff`. diff --git a/spec/pashage_extra_spec.sh b/spec/pashage_extra_spec.sh @@ -743,10 +743,8 @@ Describe 'Integrated Command Functions' End Describe 'cmd_init' - DECISION=default - It 're-encrypts the whole store using a recipient ids named like a flag' - When run cmd_init -- -p 'new-id' + When call cmd_init -- -p 'new-id' The status should be success The output should equal 'Password store recipients set at store root' The error should be blank @@ -768,6 +766,67 @@ Describe 'Integrated Command Functions' } The result of function check_git_log should be successful End + + It 'does not re-encrypt with `keep` flag' + When call cmd_init -k 'new-id' + The status should be success + The output should equal 'Password store recipients set at store root' + The error should be blank + The contents of file "${PREFIX}/.age-recipients" should equal 'new-id' + expected_log() { %text + #|Set age recipients at store root + #| + #| .age-recipients | 1 + + #| 1 file changed, 1 insertion(+) + setup_log + } + The result of function check_git_log should be successful + End + + It 'asks before re-encrypting each file with `interactive` flag' + Data + #|n + #|y + #|n + End + When call cmd_init -i 'new-id' + The status should be success + The output should equal 'Re-encrypt extra/subdir/file? [y/n]Re-encrypt stale? [y/n]Re-encrypt subdir/file? [y/n]Password store recipients set at store root' + The error should be blank + The contents of file "${PREFIX}/.age-recipients" should equal 'new-id' + expected_log() { %text + #|Set age recipients at store root + #| + #| .age-recipients | 1 + + #| stale.age | 3 +-- + #| 2 files changed, 2 insertions(+), 2 deletions(-) + setup_log + } + The result of function check_git_log should be successful + End + + usage_text() { %text + #|Usage: prg init [--interactive,-i | --keep,-k ] + #| [--path=subfolder,-p subfolder] age-recipient ... + } + + It 'displays usage when using incompatible options (`-i` then `-k`)' + PROGRAM=prg + When run cmd_init --interactive --keep 'new-id' + The status should equal 1 + The output should be blank + The error should equal "$(usage_text)" + The result of function check_git_log should be successful + End + + It 'displays usage when using incompatible options (`-k` then `-i`)' + PROGRAM=prg + When run cmd_init -ki 'new-id' + The status should equal 1 + The output should be blank + The error should equal "$(usage_text)" + The result of function check_git_log should be successful + End End Describe 'cmd_insert' diff --git a/spec/usage_spec.sh b/spec/usage_spec.sh @@ -328,9 +328,9 @@ Describe 'Command-Line Parsing' End usage_text() { %text - #|Usage: prg copy [--reencrypt,-e | --interactive,-i | --keep,-k ] - #| [--force,-f] old-path new-path - } + #|Usage: prg copy [--reencrypt,-e | --interactive,-i | --keep,-k ] + #| [--force,-f] old-path new-path + } It 'reports a bad option' cat() { @cat; } @@ -1123,6 +1123,62 @@ Describe 'Command-Line Parsing' The error should equal "$(result)" End + It 'initializes the whole store conservatively with a long option' + result() { + %text | @sed 's/\$$//' + #|$ check_sneaky_path $ + #|$ do_init recipient-1 recipient-2 + #|DECISION=keep + #|OVERWRITE=yes + } + When call cmd_init --keep recipient-1 recipient-2 + The status should be success + The output should be blank + The error should equal "$(result)" + End + + It 'initializes the whole store conservatively with a short option' + result() { + %text | @sed 's/\$$//' + #|$ check_sneaky_path $ + #|$ do_init recipient-1 recipient-2 + #|DECISION=keep + #|OVERWRITE=yes + } + When call cmd_init -k recipient-1 recipient-2 + The status should be success + The output should be blank + The error should equal "$(result)" + End + + It 'initializes the whole store interactively with a long option' + result() { + %text | @sed 's/\$$//' + #|$ check_sneaky_path $ + #|$ do_init recipient-1 recipient-2 + #|DECISION=interactive + #|OVERWRITE=yes + } + When call cmd_init --interactive recipient-1 recipient-2 + The status should be success + The output should be blank + The error should equal "$(result)" + End + + It 'initializes the whole store interactively with a short option' + result() { + %text | @sed 's/\$$//' + #|$ check_sneaky_path $ + #|$ do_init recipient-1 recipient-2 + #|DECISION=interactive + #|OVERWRITE=yes + } + When call cmd_init -i recipient-1 recipient-2 + The status should be success + The output should be blank + The error should equal "$(result)" + End + It 'initializes a subdirectory with a collapsed long option' result() { %text @@ -1179,6 +1235,34 @@ Describe 'Command-Line Parsing' The error should equal "$(result)" End + It 'interactively initializes a directory with collapsed short options' + result() { + %text + #|$ check_sneaky_path sub + #|$ do_init sub recipient + #|DECISION=interactive + #|OVERWRITE=yes + } + When call cmd_init -ipsub recipient + The status should be success + The output should be blank + The error should equal "$(result)" + End + + It 'conservatively initializes a directory with long options' + result() { + %text + #|$ check_sneaky_path sub + #|$ do_init sub recipient + #|DECISION=keep + #|OVERWRITE=yes + } + When call cmd_init --path sub --keep recipient + The status should be success + The output should be blank + The error should equal "$(result)" + End + It 'de-initializes a subdirectory' result() { %text @@ -1206,12 +1290,32 @@ Describe 'Command-Line Parsing' The error should equal "$(result)" End + usage_text() { %text + #|Usage: prg init [--interactive,-i | --keep,-k ] + #| [--path=subfolder,-p subfolder] age-recipient ... + } + It 'reports a bad option' cat() { @cat; } When run cmd_init -q arg The output should be blank - The error should equal \ - 'Usage: prg init [--path=subfolder,-p subfolder] age-recipient ...' + The error should equal "$(usage_text)" + The status should equal 1 + End + + It 'reports conflicting options (`-i` then `-k`)' + cat() { @cat; } + When run cmd_init -ik arg + The output should be blank + The error should equal "$(usage_text)" + The status should equal 1 + End + + It 'reports conflicting options (`-k` then `-i`)' + cat() { @cat; } + When run cmd_init --keep --interactive arg + The output should be blank + The error should equal "$(usage_text)" The status should equal 1 End @@ -1219,8 +1323,7 @@ Describe 'Command-Line Parsing' cat() { @cat; } When run cmd_init -p sub The output should be blank - The error should equal \ - 'Usage: prg init [--path=subfolder,-p subfolder] age-recipient ...' + The error should equal "$(usage_text)" The status should equal 1 End @@ -1228,8 +1331,7 @@ Describe 'Command-Line Parsing' cat() { @cat; } When run cmd_init -p The output should be blank - The error should equal \ - 'Usage: prg init [--path=subfolder,-p subfolder] age-recipient ...' + The error should equal "$(usage_text)" The status should equal 1 End @@ -1237,8 +1339,7 @@ Describe 'Command-Line Parsing' cat() { @cat; } When run cmd_init The output should be blank - The error should equal \ - 'Usage: prg init [--path=subfolder,-p subfolder] age-recipient ...' + The error should equal "$(usage_text)" The status should equal 1 End End diff --git a/src/pashage.sh b/src/pashage.sh @@ -1267,12 +1267,23 @@ cmd_help() { } cmd_init() { + DECISION=default OVERWRITE=yes PARSE_ERROR=no SUBDIR='' while [ $# -ge 1 ]; do case "$1" in + -i|--interactive) + [ "${DECISION}" = default ] || PARSE_ERROR=yes + DECISION=interactive + shift ;; + + -k|--keep) + [ "${DECISION}" = default ] || PARSE_ERROR=yes + DECISION=keep + shift ;; + -p|--path) if [ $# -lt 2 ]; then PARSE_ERROR=yes @@ -1290,6 +1301,15 @@ cmd_init() { SUBDIR="${1#--path=}" shift ;; + -[ik]?*) + REST="${1#-?}" + ARG="${1%"${REST}"}" + shift + set -- "${ARG}" "-${REST}" "$@" + unset ARG + unset REST + ;; + --) shift break ;; @@ -1607,7 +1627,8 @@ EOF ;; init) cat <<EOF -${F}${PROGRAM} init [--path=subfolder,-p subfolder] age-recipient ... +${F}${PROGRAM} init [--interactive,-i | --keep,-k ] +${I}${BLANKPG} [--path=subfolder,-p subfolder] age-recipient ... EOF [ "${VERBOSE}" = yes ] && cat <<EOF ${I} Initialize new password storage and use the given age recipients