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