Skip to content

Commit e73d741

Browse files
committed
[BUGFIX] auth-utils: Use loopback method to fetch authorizaton code | Fix #183
It will use either netcat or python3 to start the http server Now no need to copy paste the authorizaton ccode manually https://developers.google.com/identity/protocols/oauth2/native-app#create-code-challenge
1 parent 60598de commit e73d741

File tree

3 files changed

+163
-55
lines changed

3 files changed

+163
-55
lines changed

release/bash/gupload

+50-18
Original file line numberDiff line numberDiff line change
@@ -972,28 +972,60 @@ fi
972972
else
973973
"${QUIET:-_print_center}" "normal" " No Refresh token given, follow below steps to generate.. " "-"&&unset refresh_token_value_check_refresh_token
974974
fi
975+
server_string_check_refresh_token='Now go back to command line..'
976+
server_port_check_refresh_token='8079'
977+
while :;do
978+
: "$((server_port_check_refresh_token+=1))"
979+
if [ "$server_port_check_refresh_token" -gt 8130 ];then
980+
"${QUIET:-_print_center}" "normal" "Error: No open ports found ( 8080 to 8130 )." "-"
981+
return 1
982+
fi
983+
{ curl -Is "http://localhost:$server_port_check_refresh_token"&&continue;}||break
984+
done
985+
if command -v python 1>/dev/null&&python -V|grep -q 'Python 3';then
986+
python <<EOF 1>"$TMPFILE.code" 2>&1&
987+
from http.server import BaseHTTPRequestHandler, HTTPServer
988+
989+
class handler(BaseHTTPRequestHandler):
990+
def do_GET(self):
991+
self.send_response(200)
992+
self.end_headers()
993+
if '/?code' in self.path:
994+
message = '$server_string_check_refresh_token'
995+
self.wfile.write(bytes(message, "utf8"))
996+
997+
with HTTPServer(('', $server_port_check_refresh_token), handler) as server:
998+
server.serve_forever()
999+
EOF
1000+
_tmp_server_pid="$!"
1001+
elif command -v nc 1>/dev/null;then
1002+
printf "%b" "HTTP/1.1 200 OK\nContent-Length: $(printf "%s" "$server_string_check_refresh_token"|wc -c)\n\n$server_string_check_refresh_token"|nc -c -l -p "$server_port_check_refresh_token" 1>"$TMPFILE.code" 2>&1&
1003+
_tmp_server_pid="$!"
1004+
else
1005+
"${QUIET:-_print_center}" "normal" " Error: neither netcat (nc) nor python3 is installed. It is required to required a http server which is used in fetching authorization code. Install and proceed." "-"
1006+
return 1
1007+
fi
1008+
code_challenge_check_refresh_token="$(_epoch)authorization_code"
9751009
[ -z "$refresh_token_value_check_refresh_token" ]&&{
976-
printf "\n"&&"${QUIET:-_print_center}" "normal" "Visit the below URL, tap on allow and then enter the code obtained" " "
977-
URL="https://accounts.google.com/o/oauth2/auth?client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=$SCOPE&response_type=code&prompt=consent"
1010+
printf "\n"&&"${QUIET:-_print_center}" "normal" "Visit the below URL, follow the instructions and then come back to commandline" " "
1011+
URL="https://accounts.google.com/o/oauth2/auth?client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI%3A$server_port_check_refresh_token&scope=$SCOPE&response_type=code&code_challenge_method=plain&code_challenge=$code_challenge_check_refresh_token"
9781012
printf "\n%s\n" "$URL"
979-
unset AUTHORIZATION_CODE authorization_code AUTHORIZATION_CODE_VALID response
980-
until [ -n "$AUTHORIZATION_CODE" ]&&[ -n "$AUTHORIZATION_CODE_VALID" ];do
981-
[ -n "$AUTHORIZATION_CODE" ]&&{
982-
if _assert_regex "$authorization_code_regex" "$AUTHORIZATION_CODE";then
983-
AUTHORIZATION_CODE_VALID="true"&&continue
984-
else
985-
"${QUIET:-_print_center}" "normal" " Invalid CODE given, try again.. " "-"&&unset AUTHORIZATION_CODE authorization_code
1013+
"${QUIET:-_print_center}" "normal" " Press enter if you have completed the process in browser" "-"
1014+
read -r _
1015+
kill "$_tmp_server_pid"
1016+
if ! authorization_code="$(grep -m1 'GET.*code.*HTTP/1.1' <"$TMPFILE.code"|sed -e 's/.*GET.*code=//' -e 's/\&.*//')"&&_assert_regex "$authorization_code_regex" "$authorization_code";then
1017+
"${QUIET:-_print_center}" "normal" " Code was not fetched properly , here is some info that maybe helpful.. " "-"
1018+
"${QUIET:-_print_center}" "normal" " Code that was grabbed: $authorization_code " "-"
1019+
printf "Output of http server:\n"
1020+
cat "$TMPFILE.code"
1021+
(rm -f "$TMPFILE.code"&)
1022+
return 1
9861023
fi
987-
}
988-
{ [ -z "$authorization_code" ]&&printf "\n"&&"${QUIET:-_print_center}" "normal" " Enter the authorization code " "-";}||_clear_line 1
989-
printf -- "-> \033[?7l"
990-
read -r AUTHORIZATION_CODE&&authorization_code=1
991-
printf '\033[?7h'
992-
done
993-
response_check_refresh_token="$(curl --compressed "$CURL_PROGRESS" -X POST \
994-
--data "code=$AUTHORIZATION_CODE&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&redirect_uri=$REDIRECT_URI&grant_type=authorization_code" "$TOKEN_URL")"||:
1024+
(rm -f "$TMPFILE.code"&)
1025+
response_check_refresh_token="$(_curl --compressed "$CURL_PROGRESS" -X POST \
1026+
--data "code=$authorization_code&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&redirect_uri=$REDIRECT_URI%3A$server_port_check_refresh_token&grant_type=authorization_code&code_verifier=$code_challenge_check_refresh_token" "$TOKEN_URL")"||:
9951027
_clear_line 1 1>&2
996-
refresh_token_value_check_refresh_token="$(printf "%s\n" "$response_check_refresh_token"|_json_value refresh_token 1 1)"||{ printf "%s\n" "Error: Cannot fetch refresh token, make sure the authorization code was correct."&&return 1;}
1028+
refresh_token_value_check_refresh_token="$(printf "%s\n" "$response_check_refresh_token"|_json_value refresh_token 1 1)"||{ printf "%s\n" "Error: Cannot fetch refresh token, make sure the authorization code was correct."&&printf "%s\n" "$response_check_refresh_token"&&return 1;}
9971029
_set_value direct REFRESH_TOKEN "$refresh_token_value_check_refresh_token"
9981030
{ _check_access_token "$account_name_check_refresh_token" skip_check "$response_check_refresh_token"&&_update_config "$refresh_token_name_check_refresh_token" "$refresh_token_value_check_refresh_token" "$CONFIG";}||return 1
9991031
}

release/sh/gupload

+50-18
Original file line numberDiff line numberDiff line change
@@ -945,28 +945,60 @@ fi
945945
else
946946
"${QUIET:-_print_center}" "normal" " No Refresh token given, follow below steps to generate.. " "-"&&unset refresh_token_value_check_refresh_token
947947
fi
948+
server_string_check_refresh_token='Now go back to command line..'
949+
server_port_check_refresh_token='8079'
950+
while :;do
951+
: "$((server_port_check_refresh_token+=1))"
952+
if [ "$server_port_check_refresh_token" -gt 8130 ];then
953+
"${QUIET:-_print_center}" "normal" "Error: No open ports found ( 8080 to 8130 )." "-"
954+
return 1
955+
fi
956+
{ curl -Is "http://localhost:$server_port_check_refresh_token"&&continue;}||break
957+
done
958+
if command -v python 1>/dev/null&&python -V|grep -q 'Python 3';then
959+
python <<EOF 1>"$TMPFILE.code" 2>&1&
960+
from http.server import BaseHTTPRequestHandler, HTTPServer
961+
962+
class handler(BaseHTTPRequestHandler):
963+
def do_GET(self):
964+
self.send_response(200)
965+
self.end_headers()
966+
if '/?code' in self.path:
967+
message = '$server_string_check_refresh_token'
968+
self.wfile.write(bytes(message, "utf8"))
969+
970+
with HTTPServer(('', $server_port_check_refresh_token), handler) as server:
971+
server.serve_forever()
972+
EOF
973+
_tmp_server_pid="$!"
974+
elif command -v nc 1>/dev/null;then
975+
printf "%b" "HTTP/1.1 200 OK\nContent-Length: $(printf "%s" "$server_string_check_refresh_token"|wc -c)\n\n$server_string_check_refresh_token"|nc -c -l -p "$server_port_check_refresh_token" 1>"$TMPFILE.code" 2>&1&
976+
_tmp_server_pid="$!"
977+
else
978+
"${QUIET:-_print_center}" "normal" " Error: neither netcat (nc) nor python3 is installed. It is required to required a http server which is used in fetching authorization code. Install and proceed." "-"
979+
return 1
980+
fi
981+
code_challenge_check_refresh_token="$(_epoch)authorization_code"
948982
[ -z "$refresh_token_value_check_refresh_token" ]&&{
949-
printf "\n"&&"${QUIET:-_print_center}" "normal" "Visit the below URL, tap on allow and then enter the code obtained" " "
950-
URL="https://accounts.google.com/o/oauth2/auth?client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=$SCOPE&response_type=code&prompt=consent"
983+
printf "\n"&&"${QUIET:-_print_center}" "normal" "Visit the below URL, follow the instructions and then come back to commandline" " "
984+
URL="https://accounts.google.com/o/oauth2/auth?client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI%3A$server_port_check_refresh_token&scope=$SCOPE&response_type=code&code_challenge_method=plain&code_challenge=$code_challenge_check_refresh_token"
951985
printf "\n%s\n" "$URL"
952-
unset AUTHORIZATION_CODE authorization_code AUTHORIZATION_CODE_VALID response
953-
until [ -n "$AUTHORIZATION_CODE" ]&&[ -n "$AUTHORIZATION_CODE_VALID" ];do
954-
[ -n "$AUTHORIZATION_CODE" ]&&{
955-
if _assert_regex "$authorization_code_regex" "$AUTHORIZATION_CODE";then
956-
AUTHORIZATION_CODE_VALID="true"&&continue
957-
else
958-
"${QUIET:-_print_center}" "normal" " Invalid CODE given, try again.. " "-"&&unset AUTHORIZATION_CODE authorization_code
986+
"${QUIET:-_print_center}" "normal" " Press enter if you have completed the process in browser" "-"
987+
read -r _
988+
kill "$_tmp_server_pid"
989+
if ! authorization_code="$(grep -m1 'GET.*code.*HTTP/1.1' <"$TMPFILE.code"|sed -e 's/.*GET.*code=//' -e 's/\&.*//')"&&_assert_regex "$authorization_code_regex" "$authorization_code";then
990+
"${QUIET:-_print_center}" "normal" " Code was not fetched properly , here is some info that maybe helpful.. " "-"
991+
"${QUIET:-_print_center}" "normal" " Code that was grabbed: $authorization_code " "-"
992+
printf "Output of http server:\n"
993+
cat "$TMPFILE.code"
994+
(rm -f "$TMPFILE.code"&)
995+
return 1
959996
fi
960-
}
961-
{ [ -z "$authorization_code" ]&&printf "\n"&&"${QUIET:-_print_center}" "normal" " Enter the authorization code " "-";}||_clear_line 1
962-
printf -- "-> \033[?7l"
963-
read -r AUTHORIZATION_CODE&&authorization_code=1
964-
printf '\033[?7h'
965-
done
966-
response_check_refresh_token="$(curl --compressed "$CURL_PROGRESS" -X POST \
967-
--data "code=$AUTHORIZATION_CODE&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&redirect_uri=$REDIRECT_URI&grant_type=authorization_code" "$TOKEN_URL")"||:
997+
(rm -f "$TMPFILE.code"&)
998+
response_check_refresh_token="$(_curl --compressed "$CURL_PROGRESS" -X POST \
999+
--data "code=$authorization_code&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&redirect_uri=$REDIRECT_URI%3A$server_port_check_refresh_token&grant_type=authorization_code&code_verifier=$code_challenge_check_refresh_token" "$TOKEN_URL")"||:
9681000
_clear_line 1 1>&2
969-
refresh_token_value_check_refresh_token="$(printf "%s\n" "$response_check_refresh_token"|_json_value refresh_token 1 1)"||{ printf "%s\n" "Error: Cannot fetch refresh token, make sure the authorization code was correct."&&return 1;}
1001+
refresh_token_value_check_refresh_token="$(printf "%s\n" "$response_check_refresh_token"|_json_value refresh_token 1 1)"||{ printf "%s\n" "Error: Cannot fetch refresh token, make sure the authorization code was correct."&&printf "%s\n" "$response_check_refresh_token"&&return 1;}
9701002
_set_value direct REFRESH_TOKEN "$refresh_token_value_check_refresh_token"
9711003
{ _check_access_token "$account_name_check_refresh_token" skip_check "$response_check_refresh_token"&&_update_config "$refresh_token_name_check_refresh_token" "$refresh_token_value_check_refresh_token" "$CONFIG";}||return 1
9721004
}

src/common/auth-utils.sh

+63-19
Original file line numberDiff line numberDiff line change
@@ -336,30 +336,74 @@ _check_refresh_token() {
336336
"${QUIET:-_print_center}" "normal" " No Refresh token given, follow below steps to generate.. " "-" && unset refresh_token_value_check_refresh_token
337337
fi
338338

339+
server_string_check_refresh_token='Now go back to command line..'
340+
server_port_check_refresh_token='8079'
341+
# run a loop until an open port has been found
342+
# check for 50 ports
343+
while :; do
344+
: "$((server_port_check_refresh_token += 1))"
345+
if [ "${server_port_check_refresh_token}" -gt 8130 ]; then
346+
"${QUIET:-_print_center}" "normal" "Error: No open ports found ( 8080 to 8130 )." "-"
347+
return 1
348+
fi
349+
{ curl -Is "http://localhost:${server_port_check_refresh_token}" && continue; } || break
350+
done
351+
352+
# https://docs.python.org/3/library/http.server.html
353+
if command -v python 1> /dev/null && python -V | grep -q 'Python 3'; then
354+
python << EOF 1> "${TMPFILE}.code" 2>&1 &
355+
from http.server import BaseHTTPRequestHandler, HTTPServer
356+
357+
class handler(BaseHTTPRequestHandler):
358+
def do_GET(self):
359+
self.send_response(200)
360+
self.end_headers()
361+
if '/?code' in self.path:
362+
message = '${server_string_check_refresh_token}'
363+
self.wfile.write(bytes(message, "utf8"))
364+
365+
with HTTPServer(('', ${server_port_check_refresh_token}), handler) as server:
366+
server.serve_forever()
367+
EOF
368+
_tmp_server_pid="${!}"
369+
elif command -v nc 1> /dev/null; then
370+
# https://stackoverflow.com/a/58436505
371+
printf "%b" "HTTP/1.1 200 OK\nContent-Length: $(printf "%s" "${server_string_check_refresh_token}" | wc -c)\n\n${server_string_check_refresh_token}" | nc -c -l -p "${server_port_check_refresh_token}" 1> "${TMPFILE}.code" 2>&1 &
372+
_tmp_server_pid="${!}"
373+
else
374+
"${QUIET:-_print_center}" "normal" " Error: neither netcat (nc) nor python3 is installed. It is required to required a http server which is used in fetching authorization code. Install and proceed." "-"
375+
return 1
376+
fi
377+
378+
# https://developers.google.com/identity/protocols/oauth2/native-app#obtainingaccesstokens
379+
code_challenge_check_refresh_token="$(_epoch)authorization_code"
339380
[ -z "${refresh_token_value_check_refresh_token}" ] && {
340-
printf "\n" && "${QUIET:-_print_center}" "normal" "Visit the below URL, tap on allow and then enter the code obtained" " "
341-
URL="https://accounts.google.com/o/oauth2/auth?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&scope=${SCOPE}&response_type=code&prompt=consent"
381+
printf "\n" && "${QUIET:-_print_center}" "normal" "Visit the below URL, follow the instructions and then come back to commandline" " "
382+
URL="https://accounts.google.com/o/oauth2/auth?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}%3A${server_port_check_refresh_token}&scope=${SCOPE}&response_type=code&code_challenge_method=plain&code_challenge=${code_challenge_check_refresh_token}"
342383
printf "\n%s\n" "${URL}"
343-
unset AUTHORIZATION_CODE authorization_code AUTHORIZATION_CODE_VALID response
344-
until [ -n "${AUTHORIZATION_CODE}" ] && [ -n "${AUTHORIZATION_CODE_VALID}" ]; do
345-
[ -n "${AUTHORIZATION_CODE}" ] && {
346-
if _assert_regex "${authorization_code_regex}" "${AUTHORIZATION_CODE}"; then
347-
AUTHORIZATION_CODE_VALID="true" && continue
348-
else
349-
"${QUIET:-_print_center}" "normal" " Invalid CODE given, try again.. " "-" && unset AUTHORIZATION_CODE authorization_code
350-
fi
351-
}
352-
{ [ -z "${authorization_code}" ] && printf "\n" && "${QUIET:-_print_center}" "normal" " Enter the authorization code " "-"; } || _clear_line 1
353-
printf -- "-> \033[?7l"
354-
read -r AUTHORIZATION_CODE && authorization_code=1
355-
printf '\033[?7h'
356-
done
357-
response_check_refresh_token="$(curl --compressed "${CURL_PROGRESS}" -X POST \
358-
--data "code=${AUTHORIZATION_CODE}&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&redirect_uri=${REDIRECT_URI}&grant_type=authorization_code" "${TOKEN_URL}")" || :
384+
385+
"${QUIET:-_print_center}" "normal" " Press enter if you have completed the process in browser" "-"
386+
read -r _
387+
kill "${_tmp_server_pid}"
388+
389+
if ! authorization_code="$(grep -m1 'GET.*code.*HTTP/1.1' < "${TMPFILE}.code" | sed -e 's/.*GET.*code=//' -e 's/\&.*//')" &&
390+
_assert_regex "${authorization_code_regex}" "${authorization_code}"; then
391+
"${QUIET:-_print_center}" "normal" " Code was not fetched properly , here is some info that maybe helpful.. " "-"
392+
"${QUIET:-_print_center}" "normal" " Code that was grabbed: ${authorization_code} " "-"
393+
printf "Output of http server:\n"
394+
cat "${TMPFILE}.code"
395+
(rm -f "${TMPFILE}.code" &)
396+
return 1
397+
fi
398+
(rm -f "${TMPFILE}.code" &)
399+
400+
# https://developers.google.com/identity/protocols/oauth2/native-app#handlingresponse
401+
response_check_refresh_token="$(_curl --compressed "${CURL_PROGRESS}" -X POST \
402+
--data "code=${authorization_code}&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&redirect_uri=${REDIRECT_URI}%3A${server_port_check_refresh_token}&grant_type=authorization_code&code_verifier=${code_challenge_check_refresh_token}" "${TOKEN_URL}")" || :
359403
_clear_line 1 1>&2
360404

361405
refresh_token_value_check_refresh_token="$(printf "%s\n" "${response_check_refresh_token}" | _json_value refresh_token 1 1)" ||
362-
{ printf "%s\n" "Error: Cannot fetch refresh token, make sure the authorization code was correct." && return 1; }
406+
{ printf "%s\n" "Error: Cannot fetch refresh token, make sure the authorization code was correct." && printf "%s\n" "${response_check_refresh_token}" && return 1; }
363407

364408
_set_value direct REFRESH_TOKEN "${refresh_token_value_check_refresh_token}"
365409
{ _check_access_token "${account_name_check_refresh_token}" skip_check "${response_check_refresh_token}" &&

0 commit comments

Comments
 (0)