Software / code / prosody-modules
Comparison
mod_rest/example/rest.sh @ 5676:62c6e17a5e9d
Merge
| author | Stephen Paul Weber <singpolyma@singpolyma.net> |
|---|---|
| date | Mon, 18 Sep 2023 08:24:19 -0500 |
| parent | 5655:acd2f397ce6b |
| child | 5689:e5ad3f1f48bd |
comparison
equal
deleted
inserted
replaced
| 5675:eade7ff9f52c | 5676:62c6e17a5e9d |
|---|---|
| 3 # Copyright (c) Kim Alvefur | 3 # Copyright (c) Kim Alvefur |
| 4 # This file is MIT/X11 licensed. | 4 # This file is MIT/X11 licensed. |
| 5 | 5 |
| 6 # Dependencies: | 6 # Dependencies: |
| 7 # - https://httpie.io/ | 7 # - https://httpie.io/ |
| 8 # - https://github.com/stedolan/jq | 8 # - https://hg.sr.ht/~zash/httpie-oauth2 |
| 9 # - some sort of XDG 'open' command | 9 |
| 10 # shellcheck disable=SC1091 | |
| 10 | 11 |
| 11 # Settings | 12 # Settings |
| 12 HOST="" | 13 HOST="" |
| 13 DOMAIN="" | 14 DOMAIN="" |
| 14 | 15 |
| 15 AUTH_METHOD="session-read-only" | |
| 16 AUTH_ID="rest" | |
| 17 | |
| 18 if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/restrc" ]; then | 16 if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/restrc" ]; then |
| 19 # Config file can contain the above settings | 17 # Config file can contain the above settings |
| 20 source "${XDG_CONFIG_HOME:-$HOME/.config}/restrc" | 18 source "${XDG_CONFIG_HOME:-$HOME/.config}/restrc" |
| 19 | |
| 20 if [ -z "${SCOPE:-}" ]; then | |
| 21 SCOPE="openid xmpp" | |
| 22 fi | |
| 21 fi | 23 fi |
| 22 | 24 |
| 23 if [[ $# == 0 ]]; then | 25 if [[ $# == 0 ]]; then |
| 24 echo "${0##*/} [-h HOST] [-u USER|--login] [/path] kind=(message|presence|iq) ...." | 26 echo "${0##*/} [-h HOST] [/path] kind=(message|presence|iq) ...." |
| 25 # Last arguments are handed to HTTPie, so refer to its docs for further details | 27 # Last arguments are handed to HTTPie, so refer to its docs for further details |
| 26 exit 0 | 28 exit 0 |
| 27 fi | 29 fi |
| 28 | 30 |
| 29 if [[ "$1" == "-h" ]]; then | 31 if [[ "$1" == "-h" ]]; then |
| 43 else | 45 else |
| 44 HOST="$HOST.$DOMAIN" | 46 HOST="$HOST.$DOMAIN" |
| 45 fi | 47 fi |
| 46 fi | 48 fi |
| 47 | 49 |
| 48 if [[ "$1" == "-u" ]]; then | |
| 49 # -u username | |
| 50 AUTH_METHOD="auth" | |
| 51 AUTH_ID="$2" | |
| 52 shift 2 | |
| 53 elif [[ "$1" == "-rw" ]]; then | |
| 54 # To e.g. save Accept headers to the session | |
| 55 AUTH_METHOD="session" | |
| 56 shift 1 | |
| 57 fi | |
| 58 | |
| 59 if [[ "$1" == "--login" ]]; then | |
| 60 shift 1 | |
| 61 | |
| 62 # Check cache for OAuth client | |
| 63 if [ -f "${XDG_CACHE_HOME:-$HOME/.cache}/rest/$HOST" ]; then | |
| 64 source "${XDG_CACHE_HOME:-$HOME/.cache}/rest/$HOST" | |
| 65 fi | |
| 66 | |
| 67 OAUTH_META="$(http --check-status --json "https://$HOST/.well-known/oauth-authorization-server" Accept:application/json)" | |
| 68 AUTHORIZATION_ENDPOINT="$(echo "$OAUTH_META" | jq -e -r '.authorization_endpoint')" | |
| 69 TOKEN_ENDPOINT="$(echo "$OAUTH_META" | jq -e -r '.token_endpoint')" | |
| 70 | |
| 71 if [ -z "${OAUTH_CLIENT_INFO:-}" ]; then | |
| 72 # Register a new OAuth client | |
| 73 REGISTRATION_ENDPOINT="$(echo "$OAUTH_META" | jq -e -r '.registration_endpoint')" | |
| 74 OAUTH_CLIENT_INFO="$(http --check-status "$REGISTRATION_ENDPOINT" Content-Type:application/json Accept:application/json client_name=rest.sh client_uri="https://modules.prosody.im/mod_rest" application_type=native software_id=0bdb0eb9-18e8-43af-a7f6-bd26613374c0 redirect_uris:='["urn:ietf:wg:oauth:2.0:oob"]')" | |
| 75 mkdir -p "${XDG_CACHE_HOME:-$HOME/.cache}/rest/" | |
| 76 typeset -p OAUTH_CLIENT_INFO >> "${XDG_CACHE_HOME:-$HOME/.cache}/rest/$HOST" | |
| 77 fi | |
| 78 | |
| 79 CLIENT_ID="$(echo "$OAUTH_CLIENT_INFO" | jq -e -r '.client_id')" | |
| 80 CLIENT_SECRET="$(echo "$OAUTH_CLIENT_INFO" | jq -e -r '.client_secret')" | |
| 81 | |
| 82 if [ -n "${REFRESH_TOKEN:-}" ]; then | |
| 83 TOKEN_RESPONSE="$(http --check-status --form "$TOKEN_ENDPOINT" 'grant_type=refresh_token' "client_id=$CLIENT_ID" "client_secret=$CLIENT_SECRET" "refresh_token=$REFRESH_TOKEN")" | |
| 84 ACCESS_TOKEN="$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')" | |
| 85 if [ "$ACCESS_TOKEN" == "null" ]; then | |
| 86 ACCESS_TOKEN="" | |
| 87 fi | |
| 88 fi | |
| 89 | |
| 90 if [ -z "${ACCESS_TOKEN:-}" ]; then | |
| 91 CODE_CHALLENGE="$(head -c 33 /dev/urandom | base64 | tr /+ _-)" | |
| 92 open "$AUTHORIZATION_ENDPOINT?response_type=code&client_id=$CLIENT_ID&code_challenge=$CODE_CHALLENGE&scope=openid+prosody:user" | |
| 93 read -p "Paste authorization code: " -s -r AUTHORIZATION_CODE | |
| 94 | |
| 95 TOKEN_RESPONSE="$(http --check-status --form "$TOKEN_ENDPOINT" 'grant_type=authorization_code' "client_id=$CLIENT_ID" "client_secret=$CLIENT_SECRET" "code=$AUTHORIZATION_CODE" code_verifier="$CODE_CHALLENGE")" | |
| 96 ACCESS_TOKEN="$(echo "$TOKEN_RESPONSE" | jq -e -r '.access_token')" | |
| 97 REFRESH_TOKEN="$(echo "$TOKEN_RESPONSE" | jq -r '.refresh_token')" | |
| 98 | |
| 99 if [ "$REFRESH_TOKEN" != "null" ]; then | |
| 100 # FIXME Better type check would be nice, but nobody should ever have the | |
| 101 # string "null" as a legitimate refresh token... | |
| 102 typeset -p REFRESH_TOKEN >> "${XDG_CACHE_HOME:-$HOME/.cache}/rest/$HOST" | |
| 103 fi | |
| 104 | |
| 105 if [ -n "${COLORTERM:-}" ]; then | |
| 106 echo -ne '\e[1K\e[G' | |
| 107 else | |
| 108 echo | |
| 109 fi | |
| 110 fi | |
| 111 | |
| 112 USERINFO_ENDPOINT="$(echo "$OAUTH_META" | jq -e -r '.userinfo_endpoint')" | |
| 113 http --check-status -b --session rest "$USERINFO_ENDPOINT" "Authorization:Bearer $ACCESS_TOKEN" Accept:application/json >&2 | |
| 114 AUTH_METHOD="session-read-only" | |
| 115 AUTH_ID="rest" | |
| 116 fi | |
| 117 | |
| 118 if [[ $# == 0 ]]; then | |
| 119 # Just login? | |
| 120 exit 0 | |
| 121 fi | |
| 122 | 50 |
| 123 # For e.g /disco/example.com and such GET queries | 51 # For e.g /disco/example.com and such GET queries |
| 124 GET_PATH="" | 52 GET_PATH="" |
| 125 if [[ "$1" == /* ]]; then | 53 if [[ "$1" == /* ]]; then |
| 126 GET_PATH="$1" | 54 GET_PATH="$1" |
| 127 shift 1 | 55 shift 1 |
| 128 fi | 56 fi |
| 129 | 57 |
| 130 http --check-status -p b "--$AUTH_METHOD" "$AUTH_ID" "https://$HOST/rest$GET_PATH" "$@" | 58 https --check-status -p b --session rest -A oauth2 -a "$HOST" --oauth2-scope "$SCOPE" "$HOST/rest$GET_PATH" "$@" |