#!/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