@@ -44,11 +44,13 @@ def _handle_error_response(response_data):
4444 """Translates an error response into an exception.
4545
4646 Args:
47- response_data (Mapping): The decoded response data.
47+ response_data (Mapping | str ): The decoded response data.
4848
4949 Raises:
5050 google.auth.exceptions.RefreshError: The errors contained in response_data.
5151 """
52+ if isinstance (response_data , six .string_types ):
53+ raise exceptions .RefreshError (response_data )
5254 try :
5355 error_details = "{}: {}" .format (
5456 response_data ["error" ], response_data .get ("error_description" )
@@ -79,7 +81,13 @@ def _parse_expiry(response_data):
7981
8082
8183def _token_endpoint_request_no_throw (
82- request , token_uri , body , access_token = None , use_json = False
84+ request ,
85+ token_uri ,
86+ body ,
87+ access_token = None ,
88+ use_json = False ,
89+ expected_status_code = http_client .OK ,
90+ ** kwargs
8391):
8492 """Makes a request to the OAuth 2.0 authorization server's token endpoint.
8593 This function doesn't throw on response errors.
@@ -93,6 +101,10 @@ def _token_endpoint_request_no_throw(
93101 access_token (Optional(str)): The access token needed to make the request.
94102 use_json (Optional(bool)): Use urlencoded format or json format for the
95103 content type. The default value is False.
104+ expected_status_code (Optional(int)): The expected the status code of
105+ the token response. The default value is 200. We may expect other
106+ status code like 201 for GDCH credentials.
107+ kwargs: Additional arguments passed on to the request method.
96108
97109 Returns:
98110 Tuple(bool, Mapping[str, str]): A boolean indicating if the request is
@@ -112,32 +124,46 @@ def _token_endpoint_request_no_throw(
112124 # retry to fetch token for maximum of two times if any internal failure
113125 # occurs.
114126 while True :
115- response = request (method = "POST" , url = token_uri , headers = headers , body = body )
127+ response = request (
128+ method = "POST" , url = token_uri , headers = headers , body = body , ** kwargs
129+ )
116130 response_body = (
117131 response .data .decode ("utf-8" )
118132 if hasattr (response .data , "decode" )
119133 else response .data
120134 )
121- response_data = json .loads (response_body )
122135
123- if response .status == http_client .OK :
136+ if response .status == expected_status_code :
137+ # response_body should be a JSON
138+ response_data = json .loads (response_body )
124139 break
125140 else :
126- error_desc = response_data .get ("error_description" ) or ""
127- error_code = response_data .get ("error" ) or ""
128- if (
129- any (e == "internal_failure" for e in (error_code , error_desc ))
130- and retry < 1
131- ):
132- retry += 1
133- continue
134- return response .status == http_client .OK , response_data
135-
136- return response .status == http_client .OK , response_data
141+ # For a failed response, response_body could be a string
142+ try :
143+ response_data = json .loads (response_body )
144+ error_desc = response_data .get ("error_description" ) or ""
145+ error_code = response_data .get ("error" ) or ""
146+ if (
147+ any (e == "internal_failure" for e in (error_code , error_desc ))
148+ and retry < 1
149+ ):
150+ retry += 1
151+ continue
152+ except ValueError :
153+ response_data = response_body
154+ return response .status == expected_status_code , response_data
155+
156+ return response .status == expected_status_code , response_data
137157
138158
139159def _token_endpoint_request (
140- request , token_uri , body , access_token = None , use_json = False
160+ request ,
161+ token_uri ,
162+ body ,
163+ access_token = None ,
164+ use_json = False ,
165+ expected_status_code = http_client .OK ,
166+ ** kwargs
141167):
142168 """Makes a request to the OAuth 2.0 authorization server's token endpoint.
143169
@@ -150,6 +176,10 @@ def _token_endpoint_request(
150176 access_token (Optional(str)): The access token needed to make the request.
151177 use_json (Optional(bool)): Use urlencoded format or json format for the
152178 content type. The default value is False.
179+ expected_status_code (Optional(int)): The expected the status code of
180+ the token response. The default value is 200. We may expect other
181+ status code like 201 for GDCH credentials.
182+ kwargs: Additional arguments passed on to the request method.
153183
154184 Returns:
155185 Mapping[str, str]: The JSON-decoded response data.
@@ -159,7 +189,13 @@ def _token_endpoint_request(
159189 an error.
160190 """
161191 response_status_ok , response_data = _token_endpoint_request_no_throw (
162- request , token_uri , body , access_token = access_token , use_json = use_json
192+ request ,
193+ token_uri ,
194+ body ,
195+ access_token = access_token ,
196+ use_json = use_json ,
197+ expected_status_code = expected_status_code ,
198+ ** kwargs
163199 )
164200 if not response_status_ok :
165201 _handle_error_response (response_data )
0 commit comments