dotfiles/.local/bin/rofi/rofi-gopass

240 lines
5.8 KiB
Bash
Executable file

#!/bin/bash
# Code belongs to https://github.com/carnager/rofi-pass/
# Copyright (C) 2019 carnager
# rofi wrapper. Add custom settings here.
_rofi() {
rofi -dmenu -no-auto-select -i "$@" -theme /themes/dmenu
}
# default settings
backend=xdotool
dotool_delay=20
daemon_wait=2
autotype_delay=2
key_autotype="Return"
key_usertype="Alt+2"
key_passtype="Alt+3"
key_actions="Alt+a"
key_clipboard="Alt+1"
key_fieldtype="Return"
# read config file
get_config_file() {
configs=("$ROFI_PASS_CONFIG"
"$HOME/.config/rofi-pass/rofi-gopass.conf"
"/etc/rofi-gopass.conf")
# return the first config file with a valid path
for config in "${configs[@]}"; do
# '! -z' is needed in case ROFI_PASS_CONFIG is not set
if [[ ! -z "${config}" && -f "${config}" ]]; then
printf "%s" "$config"
return
fi
done
}
# Make sure ESC will always end the programm.
# Call this function with "exit_check $?" after each rofi call.
exit_check() {
exit_value=$1
if [[ "${exit_value}" == "1" ]]; then
exit
fi
}
clipboard() {
local entry
local key
local value
entry="${1}"
key="${2}"
value="$(gopass show "${entry}" "${key}")"
printf '%s' "${value}" | xclip -sel clip
notify-send "rofi-gopass" "Copied ${key} to clipboard\nClearing in 45 seconds."
(
sleep 45
printf '%s' "" | xclip
printf '%s' "" | xclip -selection clipboard | notify-send "rofi-gopass" "Clipboard cleared"
) &
exit
}
_ydotoold() {
if ! pgrep -x "ydotoold" >/dev/null; then
# ydotoold blocks the terminal, so we need to background it.
# Sadly this way we never know when the process finished starting up.
# Until ydotoold receives proper daemonizing we add a sleep value here.
ydotoold &
sleep "${daemon_wait}"
fi
}
_dotool() {
local mode
local key
mode="${1}"
key="${2:-null}"
case "${mode}" in
"type")
case "${backend}" in
"xdotool") xdotool type --delay "${dotool_delay}" --file - ;;
"ydotool")
_ydotoold
ydotool type --delay "${dotool_delay}" --file -
;;
esac
;;
"key")
case "${backend}" in
"xdotool") xdotool key "${key}" ;;
"ydotool")
_ydotoold
ydotool key "${key}"
;;
esac
;;
esac
}
list_passwords() {
gopass list --flat
}
autopass() {
local entry
local autotype
entry="${1}"
autotype="$(gopass show "${entry}" autotype)"
autotype="${autotype:-username :tab pass}"
for word in ${autotype}; do
case "$word" in
":tab") _dotool key Tab ;;
":space") _dotool key " " ;;
":delay") sleep "${autotype_delay}" ;;
":enter") _dotool key enter ;;
"pass") printf '%s' "$(gopass show --password "${entry}")" | _dotool type ;;
*) printf '%s' "$(gopass show "${entry}" "${word}")" | _dotool type ;;
esac
done
}
list_keys() {
# gopass has no option to only list keys, so we need to build the list ourselves.
local entry
local keys
entry="${1}"
keys="$(gopass show "${entry}")"
printf '%s\n' "${keys}" | while read -r line; do
if [[ "${line}" == *": "* ]]; then
printf '%s\n' "${line%: *}"
fi
done
}
edit_key() {
local entry
local keys
entry="${1}"
keys="$(list_keys "${entry}")"
key_name=$(printf '%s\n' "${keys}" | _rofi -mesg "Enter new key or chose existing one")
exit_check $?
value_name=$(printf '%s' "" | _rofi -mesg "Enter Value for key \"${key_name}\"")
exit_check $?
if [[ -z "${key_name}" ]]; then
printf '%s' "${value_name}" | gopass insert -a "${entry}" "${key_name}"
else
printf '%s' "${value_name}" | gopass insert "${entry}" "${key_name}"
fi
}
# For dangerous operations call this function first. You can provide a message as argument.
# Example: confirm "Are you sure you want to delete entry?"
confirm() {
local message
message="${1}"
confirm_content=(
"Yes"
"No")
confirm_menu=$(printf '%s\n' "${confirm_content[@]}" | _rofi -mesg "${message}")
exit_check $?
case "${confirm_menu}" in
"Yes") : ;;
"No") exit ;;
esac
}
custom_type() {
local entry
local keys
entry="${1}"
keys="$(list_keys "${entry}")"
key_name=$(printf '%s\n' "${keys}" | _rofi -kb-accept-entry "" -no-custom -kb-custom-1 "${key_clipboard}" -kb-custom-2 "${key_fieldtype}" -mesg "${key_clipboard}: Copy to Clipboard | ${key_fieldtype}: Type Field")
local exit_value=$?
exit_check "${exit_value}"
case "${exit_value}" in
"10") clipboard "${entry}" "${key_name}" ;;
"11")
printf '%s' "$(gopass show "${entry}" "${key_name}")" | _dotool type
exit
;;
esac
}
do_menu() {
local entry
entry="${1}"
action_menu_content=(
"< Go Back"
"---"
"Show Fields"
"Add/Edit Keys"
"Generate New Password"
"Delete Entry"
)
action_menu="$(printf '%s\n' "${action_menu_content[@]}" | _rofi -no-custom -mesg "Selected Entry: ${entry}" -p '> ')"
exit_value=$?
exit_check "${exit_value}"
case "${action_menu}" in
"< Go Back") main ;;
"Show Fields") custom_type "${entry}" ;;
"Add/Edit Keys") edit_key "${entry}" ;;
"Delete Entry")
confirm "Delete ${entry}?"
gopass rm -f "${entry}"
;;
"Generate New Password")
confirm "Generate a new password for ${entry}?"
gopass generate -f "${entry}"
;;
esac
}
main() {
entry="$(list_passwords | _rofi -kb-accept-entry "" -kb-custom-1 "${key_autotype}" -kb-custom-2 "${key_usertype}" -kb-custom-3 "${key_passtype}" -kb-custom-4 "${key_actions}" -mesg "${key_autotype}: Autotype | ${key_usertype}: Type User | ${key_passtype}: Type Pass | ${key_actions}: More Actions")"
exit_value=$?
exit_check "${exit_value}"
case "${exit_value}" in
"10")
autopass "${entry}"
exit
;;
"11")
printf '%s' "$(gopass show "${entry}" username)" | _dotool type
exit
;;
"12")
printf '%s' "$(gopass show --password "${entry}")" | _dotool type
exit
;;
esac
do_menu "${entry}"
}
main