This commit is contained in:
creme 2019-09-05 21:22:32 +02:00
parent e1e05427c5
commit 495dbc6270
No known key found for this signature in database
GPG Key ID: C147C3B7FBDF08D0
1 changed files with 75 additions and 78 deletions

153
envs
View File

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# envs - manage user-submitted scripts and apps # envs - manage user-submitted scripts and apps
# forked from tilde.team # forked from tilde.team
@ -48,7 +48,7 @@ signal_exit() { # Handle trapped signals
INT) INT)
error_exit "program interrupted by user" ;; error_exit "program interrupted by user" ;;
TERM) TERM)
echo -e "\n$PROGNAME: program terminated" >&2 printf '\n%s: program terminated\n' "$PROGNAME" >&2
graceful_exit ;; graceful_exit ;;
*) *)
error_exit "$PROGNAME: terminating on unknown signal" ;; error_exit "$PROGNAME: terminating on unknown signal" ;;
@ -59,62 +59,59 @@ signal_exit() { # Handle trapped signals
prompt_confirm() { prompt_confirm() {
while true; do while true; do
read -r -n 1 -p "${1:-continue?} [y/n]: " REPLY read -r -n 1 -p "${1:-continue?} [y/n]: " REPLY
case $REPLY in case "$REPLY" in
[yY]) echo ; return 0 ;; [yY]) echo ; return 0 ;;
[nN]) echo ; return 1 ;; [nN]) echo ; return 1 ;;
*) printf " \033[31m %s \n\033[0m" "invalid input" *) printf ' \033[31m %s \n\033[0m' "invalid input"
esac esac
done done
} }
usage() { usage() {
echo -e "\nusage: $PROGNAME [help|list|submit|about|script_name]\n" printf '\nusage: %s [help|list|submit|about|script_name]\n' "$PROGNAME"
echo " $PROGNAME list - show a list of approved userscripts" printf ' %s list - show a list of approved userscripts\n' "$PROGNAME"
echo " $PROGNAME submit - start the submission flow for your own script" printf ' %s submit - start the submission flow for your own script\n' "$PROGNAME"
[[ $(id -u) == 0 ]] && { [[ $(id -u) == 0 ]] && {
echo " $PROGNAME approve - enter the approval queue" printf ' %s approve - enter the approval queue\n' "$PROGNAME"
echo " $PROGNAME revoke <script_name> - send a script back to the author and remove from /envs/bin" printf ' %s revoke <script_name> - send a script back to the author and remove from /envs/bin\n' "$PROGNAME"
} }
echo " $PROGNAME about <script_name> - get the description for script_name"
echo " $PROGNAME <script_name> - run script_name with all remaining args are passed to the script"
if [[ :$PATH: != *:"/envs/bin":* ]] ; then if [[ :$PATH: != *:"/envs/bin":* ]] ; then
echo -e "\nadd /envs/bin to your PATH to use approved scripts without this wrapper" printf "\nadd /envs/bin to your PATH to use approved scripts without this wrapper\n"
echo "if you're using bash, run the following to add it quickly" printf "if you're using bash, run the following to add it quickly\n"
echo " echo 'export PATH=\$PATH:/envs/bin' >> ~/.bashrc && source ~/.bashrc" printf " echo 'export PATH=\$PATH:/envs/bin' >> ~/.bashrc && source ~/.bashrc\n"
fi fi
} }
help_message() { help_message() {
cat <<- _EOF_ cat <<- EOF
$PROGNAME ver. $VERSION $PROGNAME ver. $VERSION
wrapper for user-submitted scripts wrapper for user-submitted scripts
supports user submission and admin approval supports user submission and admin approval
$(usage) $(usage)
_EOF_ EOF
return return
} }
verify_script_name() { verify_script_name() {
[[ $1 == "" ]] && error_exit "please start over and enter the script name" [[ $1 == "" ]] && error_exit "please start over and enter the script name"
if [[ $(type "$1" > /dev/null 2>&1) ]]; then if [[ "$(type "$1" > /dev/null 2>&1)" ]]; then
error_exit "$1 already exists. rename your script and try again." error_exit "$1 already exists. rename your script and try again."
fi fi
[[ -x /envs/bin/$1 ]] && error_exit "$1 is already taken. rename your script and try again." [[ -x /envs/bin/"$1" ]] && error_exit "$1 is already taken. rename your script and try again."
case $1 in case "$1" in
about|description|list|ls|submit|about|help|apropos|submit|approve) help|about|description|desc|list|ls|submit|apropos|approve|revoke)
error_exit "$1 is a subcommand of envs. rename your script and try again." ;; error_exit "$1 is a subcommand of envs. rename your script and try again.";;
*) *)
return ;; return;;
esac esac
} }
submission_checklist() { submission_checklist() {
cat <<- _EOF_ cat <<- EOF
requirements for submitting a user script or program: requirements for submitting a user script or program:
- placed in your ~/bin - placed in your ~/bin
@ -122,12 +119,12 @@ requirements for submitting a user script or program:
- responds to help or --help - responds to help or --help
- no name collisions with existing scripts or $PROGNAME subcommands - no name collisions with existing scripts or $PROGNAME subcommands
_EOF_ EOF
} }
mail_body() { mail_body() {
cat <<- _EOF_ cat <<- EOF
Subject: envs script submission from $USER Subject: envs script submission from $USER
From: $USER@envs.net From: $USER@envs.net
To: creme@envs.net To: creme@envs.net
@ -146,7 +143,7 @@ you'll find the script and description in: /envs/pending-submissions/$USER/$1
run this to see the approval queue: run this to see the approval queue:
sudo envs approve sudo envs approve
_EOF_ EOF
} }
@ -158,111 +155,111 @@ trap "signal_exit INT" INT
# Parse command-line # Parse command-line
case $1 in case "$1" in
-h | --help | help) -h | --help | help)
help_message; graceful_exit ;; help_message; graceful_exit ;;
-v | --version) -v | --version)
echo $VERSION ;; printf '%s\n' "$VERSION" ;;
-* | --*) '-*' | '--*')
usage usage
error_exit "Unknown option $1" ;; error_exit "Unknown option $1" ;;
list | ls) list | ls)
echo -e "available scripts:\n" printf 'available scripts:\n'
for scr in /envs/bin/*; do for scr in /envs/bin/*; do
script_name=$(basename $scr) script_name=$(basename "$scr")
target=$(readlink -f "$scr") target=$(readlink -f "$scr")
printf '%s%s by %s%s\n' "$(tput setaf 6)" "$script_name" "$(stat -c '%U' $target)" "$(tput sgr0)" printf '%s%s by %s%s\n' "$(tput setaf 6)" "$script_name" "$(stat -c '%U' "$target")" "$(tput sgr0)"
cat /envs/descriptions/$script_name cat /envs/descriptions/"$script_name"
echo "" printf '\n'
done ;; done ;;
about | apropos | description) about | apropos | description | desc)
if [[ -f /envs/descriptions/$2 ]]; then if [[ -f /envs/descriptions/"$2" ]]; then
cat /envs/descriptions/$2 cat /envs/descriptions/"$2"
else else
echo "$2 not found. try $PROGNAME list to see available user scripts." printf '%s not found. try %s list to see available user scripts.\n' "$2" "$PROGNAME"
fi fi
;; ;;
submit) submit)
echo "hello, $USER! so it's time to submit your script?" printf "hello, %s! so it's time to submit your script?" "$USER"
submission_checklist submission_checklist
prompt_confirm "are you ready to continue?" || graceful_exit prompt_confirm "are you ready to continue?" || graceful_exit
echo -n "enter the name of your script: " printf 'enter the name of your script: '
read script_name read -r script_name
verify_script_name $script_name verify_script_name "$script_name"
if [[ -x $HOME/bin/$script_name ]]; then if [[ -x "$HOME"/bin/"$script_name" ]]; then
echo "cool, found your script" printf 'cool, found your script\n'
[[ -x /envs/pending-submissions/$USER/$script_name/$script_name ]] && error_exit "you've already submitted $script_name" [[ -x /envs/pending-submissions/"$USER"/"$script_name"/"$script_name" ]] && error_exit "you've already submitted $script_name"
else else
error_exit "$script_name not found in ~/bin" error_exit "$script_name not found in ~/bin"
fi fi
echo "enter a description of your script: " printf 'enter a description of your script:\n'
read description read -r description
echo -e "\nyour script, along with your description will be sent to the admins for approval" printf '\nyour script, along with your description will be sent to the admins for approval\n'
prompt_confirm "ready to submit?" || graceful_exit prompt_confirm "ready to submit?" || graceful_exit
# submit now # submit now
mkdir -p /envs/pending-submissions/$USER/$script_name mkdir -p /envs/pending-submissions/"$USER"/"$script_name"
ln -s $HOME/bin/$script_name /envs/pending-submissions/$USER/$script_name/$script_name ln -s "$HOME"/bin/"$script_name" /envs/pending-submissions/"$USER"/"$script_name"/"$script_name"
echo $description > /envs/pending-submissions/$USER/$script_name/description.txt echo "$description" > /envs/pending-submissions/"$USER"/"$script_name"/description.txt
mail_body $script_name "$description" | /usr/sbin/sendmail creme mail_body "$script_name" "$description" | /usr/sbin/sendmail creme
echo "script submitted. thanks! :)" ;; printf 'script submitted. thanks! :)\n' ;;
approve) approve)
[[ $(id -u) != 0 ]] && error_exit "re-run this as sudo to access the approval queue" [[ $(id -u) != 0 ]] && error_exit "re-run this as sudo to access the approval queue"
echo -e "welcome to the approval queue\n\n" printf 'welcome to the approval queue\n\n'
for user in /envs/pending-submissions/*; do for user in /envs/pending-submissions/*; do
for scr in $user/*; do for scr in "$user"/*; do
user=$(basename $user) user="$(basename "$user")"
script_name=$(basename $scr) script_name="$(basename "$scr")"
[[ -f $scr/approved ]] && continue [[ -f $scr/approved ]] && continue
script=$scr/$script_name script="$scr"/"$script_name"
echo "$script_name by $user" printf '%s by %s\n' "$script_name" "$user"
cat $scr/description.txt cat "$scr"/description.txt
prompt_confirm "approve?" || continue prompt_confirm "approve?" || continue
sudo ln -s $(readlink -f $script) /envs/bin/$script_name sudo ln -s "$(readlink -f "$script")" /envs/bin/"$script_name"
sudo cp $scr/description.txt /envs/descriptions/$script_name sudo cp "$scr"/description.txt /envs/descriptions/"$script_name"
sudo touch $scr/approved sudo touch "$scr"/approved
sudo chmod 664 /envs/descriptions/* sudo chmod 664 /envs/descriptions/*
echo "your submission of $script_name has been approved and is now available at /envs/bin/$script_name" | /usr/sbin/sendmail $user echo "your submission of $script_name has been approved and is now available at /envs/bin/$script_name" | /usr/sbin/sendmail "$user"
done done
done done
echo "~~done for now~~" ;; echo "~~done for now~~" ;;
revoke) revoke)
[[ $(id -u) != 0 ]] && error_exit "re-run this as sudo to access the revoke menu" [[ "$(id -u)" != 0 ]] && error_exit "re-run this as sudo to access the revoke menu"
[[ -f /envs/bin/$2 ]] || error_exit "$2 isn't an approved script" [[ -f /envs/bin/"$2" ]] || error_exit "$2 isn't an approved script"
prompt_confirm "revoke $2?" prompt_confirm "revoke $2?"
echo -n "please provide a reason: " printf 'please provide a reason: '
read reason read -r reason
original_script=$(readlink -f /envs/bin/$2) original_script="$(readlink -f /envs/bin/"$2")"
author=$(stat -c '%U' $original_script) author="$(stat -c '%U' "$original_script")"
sudo rm /envs/{bin,descriptions}/$2 sudo rm /envs/{bin,descriptions}/"$2"
sudo rm -rf /envs/pending-submissions/$author/$2 sudo rm -rf /envs/pending-submissions/"$author"/"$2"
echo -e "your script $2 has been returned because: $reason\nfeel free to resubmit" | /usr/sbin/sendmail $author echo -e "your script $2 has been returned because: $reason\nfeel free to resubmit" | /usr/sbin/sendmail "$author"
echo "$2 revoked and returned to author" ;; printf '%s revoked and returned to author\n' "$2" ;;
*) *)
if [[ -f /envs/bin/$1 ]]; then if [[ -f /envs/bin/"$1" ]]; then
prog=/envs/bin/$1 prog=/envs/bin/"$1"
shift shift
$prog "$@" $prog "$@"
graceful_exit graceful_exit
else else
[[ $1 == "" ]] || echo -e "$1 not found. try $PROGNAME list to see what's available\n" [[ "$1" == "" ]] || printf "%s not found. try %s list to see what's available\n" "$1" "$PROGNAME"
help_message; graceful_exit; help_message; graceful_exit;
fi ;; fi ;;