mod_rest: Implement use of refresh tokens in rest.sh example
authorKim Alvefur <zash@zash.se>
Wed, 12 Apr 2023 11:24:50 +0200
changeset 5346 e28ba69b5307
parent 5345 dcb93ffe64ae
child 5347 5c1c70e52635
mod_rest: Implement use of refresh tokens in rest.sh example Because having access tokens expire daily was becoming annoying. Now this is starting to be in dire need of refactoring.
mod_rest/example/rest.sh
--- a/mod_rest/example/rest.sh	Wed Apr 12 11:24:06 2023 +0200
+++ b/mod_rest/example/rest.sh	Wed Apr 12 11:24:50 2023 +0200
@@ -66,6 +66,8 @@
 
 	OAUTH_META="$(http --check-status --json "https://$HOST/.well-known/oauth-authorization-server" Accept:application/json)"
 	AUTHORIZATION_ENDPOINT="$(echo "$OAUTH_META" | jq -e -r '.authorization_endpoint')"
+	TOKEN_ENDPOINT="$(echo "$OAUTH_META" | jq -e -r '.token_endpoint')"
+
 	if [ -z "${OAUTH_CLIENT_INFO:-}" ]; then
 		# Register a new OAuth client
 		REGISTRATION_ENDPOINT="$(echo "$OAUTH_META" | jq -e -r '.registration_endpoint')"
@@ -77,20 +79,37 @@
 	CLIENT_ID="$(echo "$OAUTH_CLIENT_INFO" | jq -e -r '.client_id')"
 	CLIENT_SECRET="$(echo "$OAUTH_CLIENT_INFO" | jq -e -r '.client_secret')"
 
-	open "$AUTHORIZATION_ENDPOINT?response_type=code&client_id=$CLIENT_ID&scope=openid+prosody:user"
-	read -p "Paste authorization code: " -s -r AUTHORIZATION_CODE
+	if [ -n "${REFRESH_TOKEN:-}" ]; then
+		TOKEN_RESPONSE="$(http --check-status --form "$TOKEN_ENDPOINT" 'grant_type=refresh_token' "client_id=$CLIENT_ID" "client_secret=$CLIENT_SECRET" "refresh_token=$REFRESH_TOKEN")"
+		ACCESS_TOKEN="$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')"
+		if [ "$ACCESS_TOKEN" == "null" ]; then
+			ACCESS_TOKEN=""
+		fi
+	fi
+
+	if [ -z "${ACCESS_TOKEN:-}" ]; then
+		open "$AUTHORIZATION_ENDPOINT?response_type=code&client_id=$CLIENT_ID&scope=openid+prosody:user"
+		read -p "Paste authorization code: " -s -r AUTHORIZATION_CODE
 
-	TOKEN_ENDPOINT="$(echo "$OAUTH_META" | jq -e -r '.token_endpoint')"
-	TOKEN="$(http --check-status --form "$TOKEN_ENDPOINT" 'grant_type=authorization_code' "client_id=$CLIENT_ID" "client_secret=$CLIENT_SECRET" "code=$AUTHORIZATION_CODE" | jq -e -r '.access_token')"
+		TOKEN_RESPONSE="$(http --check-status --form "$TOKEN_ENDPOINT" 'grant_type=authorization_code' "client_id=$CLIENT_ID" "client_secret=$CLIENT_SECRET" "code=$AUTHORIZATION_CODE")"
+		ACCESS_TOKEN="$(echo "$TOKEN_RESPONSE" | jq -e -r '.access_token')"
+		REFRESH_TOKEN="$(echo "$TOKEN_RESPONSE" | jq -r '.refresh_token')"
+
+		if [ "$REFRESH_TOKEN" != "null" ]; then
+			# FIXME Better type check would be nice, but nobody should ever have the
+			# string "null" as a legitimate refresh token...
+			typeset -p REFRESH_TOKEN >> "${XDG_CACHE_HOME:-$HOME/.cache}/rest/$HOST"
+		fi
+
+		if [ -n "${COLORTERM:-}" ]; then
+			echo -ne '\e[1K\e[G'
+		else
+			echo
+		fi
+	fi
 
 	USERINFO_ENDPOINT="$(echo "$OAUTH_META" | jq -e -r '.userinfo_endpoint')"
-
-	if [ -n "${COLORTERM:-}" ]; then
-		echo -ne '\e[1K\e[G'
-	else
-		echo
-	fi
-	http --check-status -b --session rest "$USERINFO_ENDPOINT" "Authorization:Bearer $TOKEN" Accept:application/json >&2
+	http --check-status -b --session rest "$USERINFO_ENDPOINT" "Authorization:Bearer $ACCESS_TOKEN" Accept:application/json >&2
 	AUTH_METHOD="session-read-only"
 	AUTH_ID="rest"
 fi