[Pull request] Shortcut feature
Ondrej Vaško
ondrej.vaskoo at gmail.com
Mon Mar 27 00:51:22 CEST 2017
Dear password store users,
First of all thank you for developing such a great command line utility as
*pass* is. I am fresh IT university graduate and a while ago I started
using *pass* in a smaller company I work in, but let's go for my pull
request.
*TLDR*
Implementation of shortcuts which are written left of the password
files in *pass
ls/find/search *output and can be used with *pass show -s<number>* to
retrieve passwords not by full path, but by usually short number.
*Short description*
This commit introduces shortcut argument *-s* or *--shortcut* to *pass show
*command with which you can reference password not by full path, but by
number, which reference the specific gpg file in your password storage
directory.
*Motivation*
Long paths to keys where you have multiple options in autocomplete are
harder to write, so I was thinking about easier way to input path to
password I want to look for. I was thinking about something like short hash
for the files, or unique ID, but when I pulled actual code for pass I found
that the code is made very simple (which is great) but also harder to
extend (for example because of relying on the output of *tree* command).
After few days of thinking about an easy solution I decided to use an
*inode* as a reference shortcut for paths and implemented new argument to *pass
show* command. Inodes are easy to get (tree --inodes) and easy to find
(with *find* -inum).
*Usage*
The best use case I found is when you use *pass find/search* or *pass ls
<dir> along* with *pass show -s<shortcut>*.
Example:
*$ pass find db* #This is usual output
passwords
└── customers
├── customer1
│ ├── db01.example.com
│ │ ├── root
│ │ └── customer1
│ └── db02.example.com
│ └── root
└── customer2
└── db.customer2.com
└── root
*$ pass find db *# Output after implementing new shortcut feature
passwords
└── customers
├── customer1
│ ├── db01.example.com
│ │ ├── [123456] root
│ │ └── [123457] customer1
│ └── db02.example.com
│ └── [135412] root
└── customer2
└── db.customer2.com
└── [<NUMBER>] root
*$ pass **show -**s123456*
*> customer1rootpassword*
*Benefits*
- Inodes are usually not very long, therefore you can write pass show
-s<N> easily on keyboard, or copy shortcut with mouse (but I don't want to
encourage people to use mouse) or keyboard.
*Downsides*
- I needed to add shortcut ID to the output of tree command, so the
output is now different. I sedded out inodes for directories so the printed
tree is prettier.
- Files which have string [<number>] in name can cause troubles
(filtering of regex '\[[0-9]+\]\ \ ')
- There must not be a space after argument -s. Relevant usage is '*pass
show -s<number>'. *I reused code from other functions, so maybe other
functions behave the same.
*Git diff*
All tests passed OK with exception of *t0500-find.sh* where the changed
output was issue, so I updated regex to strip inode number ([NUMBER]) in
this test. Git diff is located in attachment.
Thank you for reading :-).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.zx2c4.com/pipermail/password-store/attachments/20170327/f55328c1/attachment.html>
-------------- next part --------------
diff --git a/src/password-store.sh b/src/password-store.sh
index bad8d4f..d38a47a 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -222,6 +222,7 @@ tmpdir() {
fi
}
+
GETOPT="getopt"
SHRED="shred -f -z"
@@ -263,9 +264,10 @@ cmd_usage() {
List passwords.
$PROGRAM find pass-names...
List passwords that match pass-names.
- $PROGRAM [show] [--clip[=line-number],-c[line-number]] pass-name
+ $PROGRAM [show] [--clip[=line-number],-c[line-number]] {pass-name|[-s[shortcut-id],--shortcut[=shortcut-id]]}
Show existing password and optionally put it on the clipboard.
If put on the clipboard, it will be cleared in $CLIP_TIME seconds.
+ Password can also be referenced by number (shortcut) shown in brackets left to the gpg file.
$PROGRAM grep search-string
Search for password files containing search-string when decrypted.
$PROGRAM insert [--echo,-e | --multiline,-m] [--force,-f] pass-name
@@ -345,21 +347,31 @@ cmd_init() {
}
cmd_show() {
- local opts selected_line clip=0 qrcode=0
- opts="$($GETOPT -o q::c:: -l qrcode::,clip:: -n "$PROGRAM" -- "$@")"
+ local opts selected_line clip=0 qrcode=0 shortcut=0
+ opts="$($GETOPT -o q::c::s:: -l qrcode::,clip::,shortcut:: -n "$PROGRAM" -- "$@")"
local err=$?
eval set -- "$opts"
while true; do case $1 in
-q|--qrcode) qrcode=1; selected_line="${2:-1}"; shift 2 ;;
-c|--clip) clip=1; selected_line="${2:-1}"; shift 2 ;;
+ -s|--shortcut) shortcut=1; shortcut_id="${2}"; shift 2 ;;
--) shift; break ;;
esac done
- [[ $err -ne 0 || ( $qrcode -eq 1 && $clip -eq 1 ) ]] && die "Usage: $PROGRAM $COMMAND [--clip[=line-number],-c[line-number]] [--qrcode[=line-number],-q[line-number]] [pass-name]"
+ [[ $err -ne 0 || ( $qrcode -eq 1 && $clip -eq 1 ) || ( -n $1 && $shortcut -eq 1 ) ]] && die "Usage: $PROGRAM $COMMAND [--clip[=line-number],-c[line-number]] [--qrcode[=line-number],-q[line-number]] {pass-name|[-s[shortcut-name],--shortcut[=shortcut-number]]}"
- local path="$1"
- local passfile="$PREFIX/$path.gpg"
+ local path=""
+
+ if [[ $shortcut -eq 1 ]]; then
+ [[ $shortcut_id =~ ^[0-9]+$ ]] || die "Shortcut ID '$shortcut_id' is not a number."
+ path=$(find $PREFIX -type f -inum $shortcut_id -printf "%P\n" | head -n1)
+ else
+ path="$1"
+ fi
+
+ local passfile="$PREFIX/${path%.gpg}.gpg"
check_sneaky_paths "$path"
+
if [[ -f $passfile ]]; then
if [[ $clip -eq 0 && $qrcode -eq 0 ]]; then
$GPG -d "${GPG_OPTS[@]}" "$passfile" || exit $?
@@ -373,13 +385,15 @@ cmd_show() {
qrcode "$pass" "$path"
fi
fi
+ elif [[ $shortcut -eq 1 && -z $path ]]; then
+ die "Error: password file with shortcut ID '$shortcut_id' does not exists in password store directory."
elif [[ -d $PREFIX/$path ]]; then
if [[ -z $path ]]; then
echo "Password Store"
else
echo "${path%\/}"
fi
- tree -C -l --noreport "$PREFIX/$path" | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' # remove .gpg at end of line, but keep colors
+ tree -C -l --noreport --inodes "$PREFIX/$path" | tail -n +2 | sed -E '/\.gpg(\x1B\[[0-9]+m)?( ->|$)/!s/\[[0-9]+\]\ \ //g' | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' # remove .gpg at end of line, but keep colors
elif [[ -z $path ]]; then
die "Error: password store is empty. Try \"pass init\"."
else
@@ -391,7 +405,7 @@ cmd_find() {
[[ $# -eq 0 ]] && die "Usage: $PROGRAM $COMMAND pass-names..."
IFS="," eval 'echo "Search Terms: $*"'
local terms="*$(printf '%s*|*' "$@")"
- tree -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g'
+ tree -C -l --noreport --inodes -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" | tail -n +2 | sed -E '/\.gpg$/!s/\[[0-9]+\]\ \ //g' | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g'
}
cmd_grep() {
diff --git a/tests/t0500-find.sh b/tests/t0500-find.sh
index 3cf6815..28e8254 100755
--- a/tests/t0500-find.sh
+++ b/tests/t0500-find.sh
@@ -12,7 +12,7 @@ test_expect_success 'Make sure find resolves correct files' '
"$PASS" generate Fishthings 122 &&
"$PASS" generate Fishies/stuff 21 &&
"$PASS" generate Fishies/otherstuff 1234 &&
- [[ $("$PASS" find fish | sed "s/^[ \`|-]*//g;s/$(printf \\x1b)\\[[0-9;]*[a-zA-Z]//g" | tr "\\n" -) == "Search Terms: fish-Fish-Fishies-otherstuff-stuff-Fishthings-" ]]
+ [[ $("$PASS" find fish | sed -E "s/\[[0-9]+\]\ \ //g" | sed "s/^[ \`|-]*//g;s/$(printf \\x1b)\\[[0-9;]*[a-zA-Z]//g" | tr "\\n" -) == "Search Terms: fish-Fish-Fishies-otherstuff-stuff-Fishthings-" ]]
'
test_done
More information about the Password-Store
mailing list