Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allowing for refresh token rotation during token refresh request #549

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions vertica_python/vertica/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,14 @@ def closed(self) -> bool:
"""Returns True if the connection is closed."""
return not self.opened()

def get_current_refresh_token(self) -> str:
"""Returns the current refresh token.

This may be different from the user supplied token if token refresh
was required and token rotation is in effect
"""
return self.oauth_refresh_token

def __str__(self) -> str:
safe_options = {key: value for key, value in self.options.items() if key != 'password'}

Expand Down Expand Up @@ -920,7 +928,7 @@ def startup_connection(self) -> bool:
# If access token is not set, will attempt to set a new one by using token refresh
if len(self.oauth_access_token) == 0 and self.oauth_manager and not self.oauth_manager.refresh_attempted:
self._logger.info("Issuing an OAuth access token using a refresh token")
self.oauth_access_token = self.oauth_manager.do_token_refresh()
self.oauth_access_token, self.oauth_refresh_token = self.oauth_manager.do_token_refresh()
self.write(messages.Password(self.oauth_access_token, message.code))
else:
self.write(messages.Password(password, message.code,
Expand All @@ -940,7 +948,7 @@ def startup_connection(self) -> bool:
raise errors.ConnectionError("Did not receive proper OAuth Authentication response from server. Please upgrade to the latest Vertica server for OAuth Support.")
self.close_socket()
self._logger.info("Issuing a new OAuth access token using a refresh token")
self.oauth_access_token = self.oauth_manager.do_token_refresh()
self.oauth_access_token, self.oauth_refresh_token = self.oauth_manager.do_token_refresh()
return True
raise errors.ConnectionError(message.error_message())
else:
Expand Down
7 changes: 6 additions & 1 deletion vertica_python/vertica/oauth_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ def get_access_token_using_refresh_token(self) -> str:
# TODO handle self.validate_cert_hostname
response = requests.post(self.token_url, headers=headers, data=params, verify=False)
response.raise_for_status()
return response.json()["access_token"]
json_response = response.json()
# If refresh token rotation is used, like in OTDS, we will get both our new valid access token as well as
# a new refresh token to use the next time we need to invoke token refresh.
if 'refresh_token' in json_response:
self.refresh_token = json_response["refresh_token"]
return response.json()["access_token"], self.refresh_token
except requests.exceptions.HTTPError as err:
msg = f'{err_msg}\n{err}\n{response.json()}'
raise OAuthTokenRefreshError(msg)
Expand Down