forked from lda/telodendria
167 lines
5 KiB
Bash
Executable file
167 lines
5 KiB
Bash
Executable file
#!/usr/bin/env sh
|
|
#
|
|
# send-patch: "The Telodendria Patch Sender"
|
|
#
|
|
# This is a simple script for posting patch files to
|
|
# a single room(generally the Telodendria patch room.)
|
|
|
|
. "$(pwd)/tools/lib/common.sh"
|
|
|
|
# Path to the patch to send.
|
|
PATCHFILE="$1"
|
|
|
|
# Tries to decompose the name and the HS from an MXID using
|
|
# sed.
|
|
UR_NAME="$(echo "$MXID" | sed "s/\@\(.*\)\:\(.*\)/\1/")"
|
|
HS_NAME="$(echo "$MXID" | sed "s/\@\(.*\)\:\(.*\)/\2/")"
|
|
|
|
# Prompts the user for a password, while disabling echo-ing.
|
|
readpwd() {
|
|
printf "$1"
|
|
stty -echo -ctlecho
|
|
read -r "$2"
|
|
echo
|
|
stty echo ctlecho
|
|
}
|
|
|
|
# Makes an HTTP request, setting the RETURN variable for the
|
|
# actual reply from the server and the ERROR_CODE variable
|
|
# for a HTTP error code.
|
|
request() {
|
|
RETURN=$(http -i "$@" 2>/dev/null)
|
|
ERROR_CODE=$(echo "$RETURN" | head -n1 | awk '{print $2}')
|
|
RETURN=$(echo "$RETURN" | sed '1,/^[[:space:]]*$/d')
|
|
}
|
|
|
|
# Prompts user to login and gives out an access token to use
|
|
# in the ACCESS_TOKEN variable
|
|
matrix_login() {
|
|
# Check authentication methods
|
|
echo "Checking authentication methods..."
|
|
request "$HS_BASE/_matrix/client/v3/login"
|
|
AUTH_METHODS=$RETURN
|
|
if [ $ERROR_CODE -ne 200 ]; then
|
|
echo "Homeserver does not support login."
|
|
exit 1
|
|
fi
|
|
if ! echo "$AUTH_METHODS" | grep "m.login.password" >/dev/null; then
|
|
echo "Homeserver does not support password authentication."
|
|
exit 1
|
|
fi
|
|
# Homeserver does support password authentication, so request
|
|
# them one.
|
|
if [ -z "$MXPW" ]; then
|
|
readpwd "Enter your Matrix password: " MXPW
|
|
fi
|
|
# Tries to login using the "Telodendria Patch Script" device
|
|
# name
|
|
JSON=$(
|
|
printf '{'
|
|
printf ' "identifier": {'
|
|
printf ' "type": "m.id.user",'
|
|
printf ' "user": %s' "$(json -e $UR_NAME)"
|
|
printf ' },'
|
|
printf ' "initial_device_display_name": "Telodendria Patch Script",'
|
|
printf ' "type": "m.login.password",'
|
|
printf ' "password": %s' "$(json -e "$MXPW")"
|
|
printf '}'
|
|
)
|
|
request -X POST -d "$JSON" $HS_BASE/_matrix/client/v3/login
|
|
LOGIN="$RETURN"
|
|
if [ $ERROR_CODE -ne 200 ]; then
|
|
echo "Login failed."
|
|
echo "$RETURN"
|
|
exit 1
|
|
fi
|
|
ACCESS_TOKEN=$(echo "$LOGIN" | json -s "access_token->@decode")
|
|
}
|
|
|
|
# Logs out of Matrix using the ACFESS_TOKEN environment variable
|
|
matrix_logout() {
|
|
if [ -z "$ACCESS_TOKEN" ]; then
|
|
echo "No access token"
|
|
exit 1
|
|
fi
|
|
request -X POST -H "Authorization: Bearer $ACCESS_TOKEN" "$HS_BASE/_matrix/client/v3/logout"
|
|
LOGOUT=$RETURN
|
|
if [ $ERROR_CODE -ne 200 ]; then
|
|
echo "Logout failed."
|
|
echo "$RETURN"
|
|
exit 1
|
|
fi
|
|
echo "Logged out."
|
|
}
|
|
|
|
send_patch() {
|
|
if [ -z "$ACCESS_TOKEN" ]; then
|
|
matrix_login
|
|
DO_LOGOUT=1
|
|
fi
|
|
# We are sucessfully logged in as our user, now let's
|
|
# try to upload and post our patch
|
|
echo "$PATCHFILE"
|
|
request -X POST \
|
|
-H "Content-Type: text/x-patch" \
|
|
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
|
-d "@$PATCHFILE" \
|
|
"$HS_BASE/_matrix/media/v3/upload"
|
|
MXCID=$RETURN
|
|
if [ $ERROR_CODE -ne 200 ]; then
|
|
echo "Upload failed."
|
|
echo "$RETURN"
|
|
matrix_logout
|
|
exit 1
|
|
fi
|
|
MXCID=$(echo "$MXCID" | json -s "content_uri->@decode")
|
|
echo "MXC ID: $MXCID"
|
|
JSON=$(
|
|
base=$(basename "$PATCHFILE")
|
|
printf '{'
|
|
printf ' "body": %s,' "$(json -e $base)"
|
|
printf ' "filename": %s,' "$(json -e $base)"
|
|
printf ' "info": {'
|
|
printf ' "mimetype": "text/x-patch",'
|
|
printf ' "size": %d' $(wc -c "$PATCHFILE" | awk '{print $1}')
|
|
printf ' },'
|
|
printf ' "msgtype": "m.file",'
|
|
printf ' "url": %s' "$(json -e $MXCID)"
|
|
printf '}'
|
|
)
|
|
http -X PUT -d "$JSON" -H "Authorization: Bearer $ACCESS_TOKEN" \
|
|
"$HS_BASE/_matrix/client/v3/rooms/$PATCHES_ROOM/send/m.room.message/$(date +%s)" \
|
|
2>/dev/null >/dev/null && echo "Patch sent."
|
|
|
|
# Log out if we generated an access token
|
|
if [ "$DO_LOGOUT" -eq "1" ]; then
|
|
matrix_logout
|
|
fi
|
|
}
|
|
|
|
# Check if the patch file is valid.
|
|
if [ "$(basename "$PATCHFILE" .patch)" = "$PATCHFILE" ] || [ ! -f "$PATCHFILE" ]; then
|
|
echo "Format: $0 file.patch"
|
|
exit 1
|
|
fi
|
|
echo "Sending file '$PATCHFILE'"
|
|
echo "Checking homeserver's real address using .well-known..."
|
|
request "https://$HS_NAME/.well-known/matrix/client"
|
|
case "$ERROR_CODE" in
|
|
"200")
|
|
WELL_KNOWN=$RETURN
|
|
if [ -z "$WELL_KNOWN" ]; then
|
|
echo "well-known test returned 200 but no correct input was given."
|
|
exit 1
|
|
fi
|
|
# well-known entry is correct, we can now store our base endpoint
|
|
HS_BASE=$(printf "$WELL_KNOWN" | json -s "m.homeserver->base_url->@decode") && send_patch
|
|
;;
|
|
*)
|
|
echo "$ERROR_CODE"
|
|
|
|
echo "well-known test failed."
|
|
printf "Please enter your homeserver base URL: "
|
|
read -r HS_BASE
|
|
echo
|
|
send_patch
|
|
;;
|
|
esac
|