This repository has been archived on 2022-02-23. You can view files and clone it, but cannot push or open issues or pull requests.
archive_hook.sh/databases/unix

297 lines
7.5 KiB
Bash
Executable File

#! /bin/bash
# TODO: replace with ~/database
db="$HOME/webhooks"
# Make sure we don't fallback to a simple "*.foo" when no files matched the glob pattern
shopt -s nullglob
# These are the functions used by commands, search for ENTRYPOINT to see where the script starts!
from_url() {
# Return hex representation of URL
echo -n "$@" | base64
}
from_hex() {
# Return string representation (URL) of hex
echo -n "$@" | base64 -d
}
# When we reach those commands, $user is necessarily set
help_cmd() {
echo "TODO provide some help here :D"
}
list_cmd() {
# If we receive a repo argument, we print the subscribers to it
if [ $# -gt 0 ]; then
r="$1"
rhex="$(from_url "$r")"
if [ ! -f $db/."$rhex".secret ]; then
echo "ERROR: Repository $r not found"
exit 1
fi
for u in "$db"/"$rhex".*; do
# For each subscriber, print the username
u="$(basename "$u")"
u="${u#$rhex.}"
echo "$u"
done
exit 0
fi
for f in "$db"/*."$user"; do
rhex="$(basename "$f" ".$user")"
r="$(from_hex "$rhex")"
output="$r"
owner="$(cat "$db/.$rhex.owner")"
if [[ "$owner" = "$user" ]]; then
secret="$(cat "$db/.$rhex.secret")"
output="$output\t$secret"
fi
# Need -e to interpret the \t
echo -e "$output"
done
# New iteration for unsubscribed tasks you still own
for f in $db/owned-by/$user/*; do
rhex="$(basename "$f")"
owner="$(cat "$db/.$rhex.owner")"
if [[ "$owner" != "$user" ]]; then
echo "FATAL ERROR: HOW CAN THIS HAPPEN?"
echo "$rhex claims owner is $owner, but $user claims it as well."
exit 1
fi
if [ -f "$db/$rhex.$user" ]; then
# user is subscribed so it's already printed
continue
fi
r="$(from_hex "$rhex")"
secret="$(cat "$db/.$rhex.secret")"
output="$rhex\t$secret\tx"
# Still need -e for tabulations
echo -e "$output"
done
}
add_cmd() {
if [ $# -lt 1 ]; then
echo "ERROR: You need to provide a repo to add!"
fi
r="$1"
rhex="$(from_url "$1")"
# Check if the repository is already registered
if [ -f "$db/.$rhex.owner" ]; then
# If it is, we try to subscribe instead
echo "[forgehook] This repository is already registered, subscribing to it."
subscribe_cmd "$r"
exit $?
fi
# Ensure we can clone the repo
tmp="$(mktemp -d)"
if ! git clone "$r" "$tmp/repo"; then
rm -r "$tmp"
echo "ERROR: The repository cannot be cloned: $r"
exit 1
fi
# Need to force for .git files
rm -rf "$tmp"
echo "$user" > $db/."$rhex".owner
if [ ! -d $db/owned-by/"$user" ]; then
if ! mkdir $db/owned-by/"$user"; then
echo "FATAL ERROR: Cannot create $db/owned-by/$user. WTF?"
exit 1
fi
fi
touch $db/owned-by/"$user"/"$rhex"
if [ -z ${2+NULL} ]; then
secret="$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c32)"
else
secret="$2"
fi
echo "$secret" > $db/."$rhex".secret
echo "[forgehook] Your secret for $r is now:"
echo "$secret"
subscribe_cmd "$r"
}
remove_cmd() {
FORCE=0
if [ $# -lt 1 ]; then
echo "ERROR: You need to provide a repo to remove!"
elif [ $# -gt 1 ]; then
if [[ "$2" = "force" ]] || [[ "$2" = "-f" ]] || [[ "$2" = "--force" ]]; then
FORCE=1
else
echo "ERROR: Unrecognized argument $2"
fi
fi
# If the command is not forced, unsubscribe instead
if [[ $FORCE = 0 ]]; then
unsubscribe_cmd "$1"
exit $?
fi
# We want to remove it for real, for all users
r="$1"
rhex="$(from_url "$1")"
# Check the repo is registered with us
if [ ! -f "$db/.$rhex.owner" ]; then
echo "ERROR: This repo isn't registered $r"
exit 1
fi
owner="$(cat $db/."$rhex".owner)"
if [[ "$owner" != "$user" ]]; then
echo "ERROR: Repository $r is claimed by $owner, you cannot remove it."
exit 1
fi
rm $db/owned-by/"$user"/"$rhex"
rm $db/."$rhex".owner
rm $db/."$rhex".secret
# Do not fail if there are no more subscriptions
rm -f $db/"$rhex".*
echo "[forgehook] Successfully removed $r"
}
subscribe_cmd() {
if [ $# -lt 1 ]; then
echo "ERROR: You need to provide a repository URL to subscribe to"
exit 0
fi
r="$1"
rhex="$(from_url $r)"
if [ ! -f $db/."$rhex".owner ]; then
echo "ERROR: Repository $r hasn't been added yet, maybe try:"
echo "forgehook add \"$r\""
exit 1
fi
if [ -f $db/"$rhex"."$user" ]; then
echo "[forgehook] You are already subscribed to $r"
exit 0
fi
touch $db/"$rhex"."$user"
owner="$(cat $db/."$rhex".owner)"
echo "[forgehook] Subscribed to $r (owner: $owner)"
}
unsubscribe_cmd() {
if [ $# -lt 1 ]; then
echo "ERROR: You need to provide a repository URL to subscribe to"
exit 1
fi
r="$1"
rhex="$(from_url "$r")"
if [ ! -f $db/."$rhex".owner ]; then
echo "ERROR: Repository $r hasn't been added yet, cannot unsubscribe. Run forgehook without argument to list your repositories"
exit 1
fi
if [ ! -f $db/"$rhex"."$user" ]; then
echo "ERROR: You are not subscribed to repository $r"
exit 1
fi
rm $db/"$rhex"."$user"
echo "[forgehook] Successfully unsubscribed from $r"
}
secret_cmd() {
if [ $# -lt 1 ]; then
echo "ERROR: You need to provide a repository URL to view/change its secret"
exit 1
fi
r="$1"
rhex="$(from_url "$r")"
if [ ! -f $db/."$rhex".owner ]; then
echo "ERROR: Repository $r hasn't been added yet. Run forgehook without argument to list your repositories"
exit 1
fi
owner="$(cat $db/."$rhex".owner)"
db_owner="$(find /usr/local/bin/forgehook-db -maxdepth 0 -printf '%u')"
if [[ "$owner" != "$user" ]] && [[ "$(id -gn $SUDO_GID)" != "$db_owner" ]]; then
# TODO: when running with group forgehook, we don't exit because it's an endpoint asking (done?)
echo "ERROR: Repository $r is owned by $owner"
exit 1
fi
if [ $# -gt 1 ]; then
secret="$2"
echo "$secret" > "$db/.$rhex.secret"
echo "[forgehook] Your secret for $r is now:"
echo "$secret"
exit 0
fi
cat $db/."$rhex".secret
}
# ENTRYPOINT
# We trust sudo security!
user="$SUDO_USER"
# If no argument is supplied, we do the list
if [[ $# = 0 ]]; then
list_cmd
exit $?
fi
# Ensure directoies are correctly setup
if [ ! -d $db ]; then
if ! mkdir $db; then
echo "$(id -run)"
echo "FATAL ERROR: Cannot create $db"
exit 1
fi
fi
if [ ! -d $db/owned-by/"$user" ]; then
# -p in case owned-by/ doesn't exist yet
if ! mkdir -p $db/owned-by/"$user"; then
echo "FATAL ERROR: Cannot create $db/owned-by/$user"
exit 1
fi
fi
command="$1"
# Remove first argument from arguments
shift
case $command in
"help"|"-f"|"--help")
help_cmd
;;
"list")
list_cmd $@
;;
"add")
add_cmd $@
;;
"remove"|"rm")
remove_cmd $@
;;
"subscribe"|"sub")
subscribe_cmd $@
;;
"unsubscribe"|"unsub")
unsubcribe_cmd $@
;;
"secret")
secret_cmd $@
;;
*)
echo "ERROR: Command not found: $command"
help_cmd
exit 1
esac