From 94b225020f1bccbc1a4b384aea7afcf1b9832a3c Mon Sep 17 00:00:00 2001 From: Jesse Whitehouse Date: Thu, 11 May 2023 15:21:54 -0500 Subject: [PATCH 1/3] Oauth: ignore ~/.netrc file for requests to unauthenticated endpoints https://requests.readthedocs.io/en/latest/user/authentication/#new-forms-of-authentication Closes #121 Affects databricks/dbt-databricks#337 Signed-off-by: Jesse Whitehouse --- src/databricks/sql/auth/oauth.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/databricks/sql/auth/oauth.py b/src/databricks/sql/auth/oauth.py index a2b9c6ed6..9017f694f 100644 --- a/src/databricks/sql/auth/oauth.py +++ b/src/databricks/sql/auth/oauth.py @@ -18,6 +18,19 @@ logger = logging.getLogger(__name__) +class IgnoreNetrcAuth(requests.auth.AuthBase): + """This auth method is a no-op. + + We use it to force requestslib to not use .netrc to write auth headers + when making .post() requests to the oauth token endpoints, since these + don't require authentication. + + In cases where .netrc is outdated or corrupt, these requests will fail. + + See issue #121 + """ + def __call__(self, r): + return r class OAuthManager: def __init__( @@ -43,7 +56,7 @@ def __fetch_well_known_config(self, hostname: str): known_config_url = self.idp_endpoint.get_openid_config_url(hostname) try: - response = requests.get(url=known_config_url) + response = requests.get(url=known_config_url, auth=IgnoreNetrcAuth()) except RequestException as e: logger.error( f"Unable to fetch OAuth configuration from {known_config_url}.\n" @@ -149,7 +162,7 @@ def __send_token_request(token_request_url, data): "Accept": "application/json", "Content-Type": "application/x-www-form-urlencoded", } - response = requests.post(url=token_request_url, data=data, headers=headers) + response = requests.post(url=token_request_url, data=data, headers=headers, auth=IgnoreNetrcAuth()) return response.json() def __send_refresh_token_request(self, hostname, refresh_token): From 71e878bf372616736a013857d0a98f1304206895 Mon Sep 17 00:00:00 2001 From: Jesse Whitehouse Date: Thu, 11 May 2023 15:22:17 -0500 Subject: [PATCH 2/3] Black src files Signed-off-by: Jesse Whitehouse --- src/databricks/sql/auth/oauth.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/databricks/sql/auth/oauth.py b/src/databricks/sql/auth/oauth.py index 9017f694f..78f516fee 100644 --- a/src/databricks/sql/auth/oauth.py +++ b/src/databricks/sql/auth/oauth.py @@ -18,20 +18,23 @@ logger = logging.getLogger(__name__) + class IgnoreNetrcAuth(requests.auth.AuthBase): """This auth method is a no-op. - + We use it to force requestslib to not use .netrc to write auth headers when making .post() requests to the oauth token endpoints, since these don't require authentication. In cases where .netrc is outdated or corrupt, these requests will fail. - + See issue #121 """ + def __call__(self, r): return r + class OAuthManager: def __init__( self, @@ -162,7 +165,9 @@ def __send_token_request(token_request_url, data): "Accept": "application/json", "Content-Type": "application/x-www-form-urlencoded", } - response = requests.post(url=token_request_url, data=data, headers=headers, auth=IgnoreNetrcAuth()) + response = requests.post( + url=token_request_url, data=data, headers=headers, auth=IgnoreNetrcAuth() + ) return response.json() def __send_refresh_token_request(self, hostname, refresh_token): From 40e2dd26b2ae30ee3c0ff3be561d99f0e2fc9c54 Mon Sep 17 00:00:00 2001 From: Jesse Whitehouse Date: Mon, 10 Jul 2023 21:39:58 -0500 Subject: [PATCH 3/3] Update changelog Signed-off-by: Jesse Whitehouse --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e9d2963a..961423ad1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Add support for Cloud Fetch - Fix: Revised SQLAlchemy dialect and examples for compatibility with SQLAlchemy==1.3.x +- Fix: oauth would fail if expired credentials appeared in ~/.netrc ## 2.7.0 (2023-06-26)