Remove placeholder.sh (#16)
This commit is contained in:
184
placeholder.sh
184
placeholder.sh
@@ -1,184 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
LENGTH=$(head -c 4 | perl -ne 'print unpack("L", $_)')
|
|
||||||
declare -gr REQUEST=$(head -c $LENGTH)
|
|
||||||
VERSION=3000000
|
|
||||||
|
|
||||||
# Write a number as little-endian binary
|
|
||||||
function writelen()
|
|
||||||
{
|
|
||||||
printf
|
|
||||||
}
|
|
||||||
|
|
||||||
# Require a command to be present, and quit if it's not
|
|
||||||
function require()
|
|
||||||
{
|
|
||||||
if ! `command -v "$1" >/dev/null`; then
|
|
||||||
OUTPUT="{\n \"status\": \"error\"\n "version": $VERSION,\n \"params\": {\n \"message\": \"Required dependency '$1' is missing\"\n }, \"code\": 1\n}"
|
|
||||||
LANG=C LC_ALL=C LENGTH=${#OUTPUT}
|
|
||||||
echo -n
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Echo to stderr with failure status code
|
|
||||||
function fail()
|
|
||||||
{
|
|
||||||
echo "$@" >&2
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# trim leading and trailing whitespace
|
|
||||||
function trim()
|
|
||||||
{
|
|
||||||
echo "$1" | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Build an error response message
|
|
||||||
function error()
|
|
||||||
{
|
|
||||||
if [ -n "$1" ]; then
|
|
||||||
ERROR="$1"
|
|
||||||
else
|
|
||||||
ERROR=$(cat)
|
|
||||||
fi
|
|
||||||
[ -n "$2" ] && CODE="$2" || CODE=1
|
|
||||||
OUTPUT="$(jq -n '.status = "error"' | jq --arg message "$ERROR" --arg code "$CODE" '.params.message = $message | .code = ($code|tonumber)')"
|
|
||||||
perl -e "print pack('L', ${#OUTPUT})"
|
|
||||||
echo -n "$OUTPUT"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Wrap a shell command and bail with a valid response message on error
|
|
||||||
function wrap()
|
|
||||||
{
|
|
||||||
. <({ STDERR=$({ STDOUT=$("$@"); EXIT=$?; } 2>&1; declare -p EXIT >&2; declare -p STDOUT >&2); declare -p STDERR; } 2>&1; )
|
|
||||||
if [ $EXIT -gt 0 ] || [ -n "$STDERR" ]; then
|
|
||||||
if [ -n "$STDERR" ]; then
|
|
||||||
echo -n "$STDERR" | error
|
|
||||||
elif [ -n "$STDOUT" ]; then
|
|
||||||
echo -n "$STDOUT" | error
|
|
||||||
else
|
|
||||||
error "$@" $EXIT
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
OUTPUT="$(jq -n --arg version $VERSION --arg response "$STDOUT" '.status = "ok" | .version = $version | .data = ($response | if .[:1] == "{" then ( . | fromjson) else . end)')"
|
|
||||||
perl -e "print pack('L', ${#OUTPUT})"
|
|
||||||
echo -n "$OUTPUT"
|
|
||||||
fi
|
|
||||||
return $EXIT
|
|
||||||
}
|
|
||||||
|
|
||||||
# jq wrapper around the request
|
|
||||||
function rq()
|
|
||||||
{
|
|
||||||
jq -r "$@" <<< "$REQUEST"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Supply per-store configuration
|
|
||||||
function configure()
|
|
||||||
{
|
|
||||||
set -e
|
|
||||||
|
|
||||||
declare -A STORES
|
|
||||||
. <(rq '.settings.stores | to_entries | map("STORES[\(.key|@sh)]=\(.value.path|@sh)")[]')
|
|
||||||
|
|
||||||
for STORE in "${!STORES[@]}"; do
|
|
||||||
STOREPATH=$(echo "${STORES["$STORE"]}" | sed 's/^~/$HOME/' | envsubst)
|
|
||||||
[ -d "$STOREPATH" ] || fail "Store directory for '$STORE' does not exist: $STOREPATH"
|
|
||||||
|
|
||||||
if [ -f "$STOREPATH/.browserpass.json" ]; then
|
|
||||||
STORES["$STORE"]=$(cat "$STOREPATH/.browserpass.json")
|
|
||||||
else
|
|
||||||
STORES["$STORE"]=
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
[ -n "$PASSWORD_STORE_DIR" ] || PASSWORD_STORE_DIR="~/.password-store"
|
|
||||||
OUTPUT="$(jq -n --arg defaultPath "$PASSWORD_STORE_DIR" '.defaultStore.path = $defaultPath')"
|
|
||||||
|
|
||||||
STOREPATH=$(echo "$PASSWORD_STORE_DIR" | sed 's/^~/$HOME/' | envsubst)
|
|
||||||
if [ -f "$STOREPATH/.browserpass.json" ]; then
|
|
||||||
OUTPUT=$(jq --arg settings "$(cat "$STOREPATH/.browserpass.json")" '.defaultStore.settings = $settings' <<< "$OUTPUT")
|
|
||||||
else
|
|
||||||
OUTPUT=$(jq '.defaultSettings = ""' <<< "$OUTPUT")
|
|
||||||
fi
|
|
||||||
|
|
||||||
for STORE in "${!STORES[@]}"; do
|
|
||||||
OUTPUT=$(jq --arg store "$STORE" --arg settings "${STORES[$STORE]}" '.storeSettings[$store] = $settings' <<< "$OUTPUT")
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "$OUTPUT"
|
|
||||||
}
|
|
||||||
|
|
||||||
# List all available logins by store
|
|
||||||
function list()
|
|
||||||
{
|
|
||||||
set -e
|
|
||||||
|
|
||||||
declare -A STORES
|
|
||||||
. <(rq '.settings.stores | to_entries | map("STORES[\(.key|@sh)]=\(.value.path|@sh)")[]')
|
|
||||||
for STORE in "${!STORES[@]}"; do
|
|
||||||
STOREPATH=$(echo "${STORES["$STORE"]}" | sed 's/^~/$HOME/' | envsubst)
|
|
||||||
[ -d "$STOREPATH" ] || fail "Store directory for '$STORE' does not exist: $STOREPATH"
|
|
||||||
|
|
||||||
STORES[$STORE]="$(find -L "$STOREPATH" -type f -name '*.gpg' -printf '%P\n' | jq -R -s 'split("\n") | map(select(length > 0)) ')"
|
|
||||||
done
|
|
||||||
|
|
||||||
OUTPUT='{}'
|
|
||||||
for STORE in "${!STORES[@]}"; do
|
|
||||||
OUTPUT=$(jq --arg store "$STORE" --arg files "${STORES[$STORE]}" '.files[$store] = ($files|fromjson)' <<< "$OUTPUT")
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "$OUTPUT"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fetch the specified fields from a single login
|
|
||||||
function fetch()
|
|
||||||
{
|
|
||||||
set -e
|
|
||||||
|
|
||||||
STORE="$(rq .store)"
|
|
||||||
FILE="$(rq .file)"
|
|
||||||
|
|
||||||
# sanity-check variables
|
|
||||||
[ -n "$STORE" ] || fail ".store is not set"
|
|
||||||
[ -n "$FILE" ] || fail ".file is not set"
|
|
||||||
|
|
||||||
# get file path
|
|
||||||
STOREPATH="$(rq --arg store "$STORE" '.settings.stores[$store].path//empty' | sed 's/^~/$HOME/' | envsubst)"
|
|
||||||
[ -n "$STOREPATH" ] || fail "Store path is empty"
|
|
||||||
[ -d "$STOREPATH" ] || fail "Store directory for '$STORE' does not exist: $STOREPATH"
|
|
||||||
FILEPATH="$STOREPATH/$FILE"
|
|
||||||
|
|
||||||
# get file contents
|
|
||||||
[ -f "$FILEPATH" ] || fail "Requested file does not exist: $STORE:$FILE"
|
|
||||||
DATA="$(gpg -q --decrypt "$FILEPATH")"
|
|
||||||
|
|
||||||
# build output
|
|
||||||
echo "$(jq -n --arg data "$DATA" '.contents = $data')"
|
|
||||||
}
|
|
||||||
|
|
||||||
function run()
|
|
||||||
{
|
|
||||||
case "$(rq .action)" in
|
|
||||||
configure) configure; return $?;;
|
|
||||||
list) list; return $?;;
|
|
||||||
fetch) fetch; return $?;;
|
|
||||||
*) echo "Unknown action: $(rq .action)" >&2; return 1;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ensure dependencies are present
|
|
||||||
require cat
|
|
||||||
require envsubst
|
|
||||||
require find
|
|
||||||
require gpg
|
|
||||||
require grep
|
|
||||||
require head
|
|
||||||
require jq
|
|
||||||
require perl
|
|
||||||
require sed
|
|
||||||
require tac
|
|
||||||
|
|
||||||
# Run the client
|
|
||||||
wrap run
|
|
Reference in New Issue
Block a user