Skip to content

Commit 62e49c1

Browse files
authored
Ensure Dropbox error is thrown in refresh access token (#407)
Ensure Dropbox error is thrown in refresh access token
1 parent 0154374 commit 62e49c1

File tree

2 files changed

+51
-38
lines changed

2 files changed

+51
-38
lines changed

dropbox/dropbox_client.py

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,6 @@ def refresh_access_token(self, host=API_HOST, scope=None):
376376
:param scope: list of permission scopes for access token
377377
:return:
378378
"""
379-
380379
if scope is not None and (len(scope) == 0 or not isinstance(scope, list)):
381380
raise BadInputException("Scope list must be of type list")
382381

@@ -401,12 +400,7 @@ def refresh_access_token(self, host=API_HOST, scope=None):
401400
if self._timeout:
402401
timeout = self._timeout
403402
res = self._session.post(url, data=body, timeout=timeout)
404-
if res.status_code == 400 and res.json()['error'] == 'invalid_grant':
405-
request_id = res.headers.get('x-dropbox-request-id')
406-
err = stone_serializers.json_compat_obj_decode(
407-
AuthError_validator, 'invalid_access_token')
408-
raise AuthError(request_id, err)
409-
res.raise_for_status()
403+
self.raise_dropbox_error_for_resp(res)
410404

411405
token_content = res.json()
412406
self._oauth2_access_token = token_content["access_token"]
@@ -596,53 +590,72 @@ def request_json_string(self,
596590
verify=True,
597591
timeout=timeout,
598592
)
599-
593+
self.raise_dropbox_error_for_resp(r)
600594
request_id = r.headers.get('x-dropbox-request-id')
601-
if r.status_code >= 500:
602-
raise InternalServerError(request_id, r.status_code, r.text)
603-
elif r.status_code == 400:
604-
raise BadInputError(request_id, r.text)
605-
elif r.status_code == 401:
595+
if r.status_code in (403, 404, 409):
596+
raw_resp = r.content.decode('utf-8')
597+
return RouteErrorResult(request_id, raw_resp)
598+
599+
if route_style == self._ROUTE_STYLE_DOWNLOAD:
600+
raw_resp = r.headers['dropbox-api-result']
601+
else:
606602
assert r.headers.get('content-type') == 'application/json', (
607603
'Expected content-type to be application/json, got %r' %
608604
r.headers.get('content-type'))
605+
raw_resp = r.content.decode('utf-8')
606+
if route_style == self._ROUTE_STYLE_DOWNLOAD:
607+
return RouteResult(raw_resp, r)
608+
else:
609+
return RouteResult(raw_resp)
610+
611+
def raise_dropbox_error_for_resp(self, res):
612+
"""Checks for errors from a res and handles appropiately.
613+
614+
:param res: Response of an api request.
615+
"""
616+
request_id = res.headers.get('x-dropbox-request-id')
617+
if res.status_code >= 500:
618+
raise InternalServerError(request_id, res.status_code, res.text)
619+
elif res.status_code == 400:
620+
try:
621+
if res.json()['error'] == 'invalid_grant':
622+
request_id = res.headers.get('x-dropbox-request-id')
623+
err = stone_serializers.json_compat_obj_decode(
624+
AuthError_validator, 'invalid_access_token')
625+
raise AuthError(request_id, err)
626+
else:
627+
raise BadInputError(request_id, res.text)
628+
except ValueError:
629+
raise BadInputError(request_id, res.text)
630+
elif res.status_code == 401:
631+
assert res.headers.get('content-type') == 'application/json', (
632+
'Expected content-type to be application/json, got %r' %
633+
res.headers.get('content-type'))
609634
err = stone_serializers.json_compat_obj_decode(
610-
AuthError_validator, r.json()['error'])
635+
AuthError_validator, res.json()['error'])
611636
raise AuthError(request_id, err)
612-
elif r.status_code == HTTP_STATUS_INVALID_PATH_ROOT:
637+
elif res.status_code == HTTP_STATUS_INVALID_PATH_ROOT:
613638
err = stone_serializers.json_compat_obj_decode(
614-
PathRootError_validator, r.json()['error'])
639+
PathRootError_validator, res.json()['error'])
615640
raise PathRootError(request_id, err)
616-
elif r.status_code == 429:
641+
elif res.status_code == 429:
617642
err = None
618-
if r.headers.get('content-type') == 'application/json':
643+
if res.headers.get('content-type') == 'application/json':
619644
err = stone_serializers.json_compat_obj_decode(
620-
RateLimitError_validator, r.json()['error'])
645+
RateLimitError_validator, res.json()['error'])
621646
retry_after = err.retry_after
622647
else:
623-
retry_after_str = r.headers.get('retry-after')
648+
retry_after_str = res.headers.get('retry-after')
624649
if retry_after_str is not None:
625650
retry_after = int(retry_after_str)
626651
else:
627652
retry_after = None
628653
raise RateLimitError(request_id, err, retry_after)
629-
elif 200 <= r.status_code <= 299:
630-
if route_style == self._ROUTE_STYLE_DOWNLOAD:
631-
raw_resp = r.headers['dropbox-api-result']
632-
else:
633-
assert r.headers.get('content-type') == 'application/json', (
634-
'Expected content-type to be application/json, got %r' %
635-
r.headers.get('content-type'))
636-
raw_resp = r.content.decode('utf-8')
637-
if route_style == self._ROUTE_STYLE_DOWNLOAD:
638-
return RouteResult(raw_resp, r)
639-
else:
640-
return RouteResult(raw_resp)
641-
elif r.status_code in (403, 404, 409):
642-
raw_resp = r.content.decode('utf-8')
643-
return RouteErrorResult(request_id, raw_resp)
644-
else:
645-
raise HttpError(request_id, r.status_code, r.text)
654+
elif res.status_code in (403, 404, 409):
655+
# special case handled by requester
656+
return
657+
elif not (200 <= res.status_code <= 299):
658+
raise HttpError(request_id, res.status_code, res.text)
646659

647660
def _get_route_url(self, hostname, route_name):
648661
"""Returns the URL of the route.

test/integration/test_dropbox.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def test_default_oauth2_urls(self):
153153
def test_bad_auth(self):
154154
# Test malformed token
155155
malformed_token_dbx = Dropbox(MALFORMED_TOKEN)
156-
with pytest.raises(BadInputError) as cm:
156+
with pytest.raises(BadInputError,) as cm:
157157
malformed_token_dbx.files_list_folder('')
158158
assert 'token is malformed' in cm.value.message
159159

0 commit comments

Comments
 (0)