Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9f9e96d

Browse files
authored
[PECO-1715] Remove username/password (BasicAuth) auth option (databricks#409)
Signed-off-by: Jacky Hu <[email protected]>
1 parent 5d869d0 commit 9f9e96d

File tree

6 files changed

+17
-69
lines changed

6 files changed

+17
-69
lines changed

src/databricks/sql/auth/auth.py

+7-10
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from databricks.sql.auth.authenticators import (
55
AuthProvider,
66
AccessTokenAuthProvider,
7-
BasicAuthProvider,
87
ExternalAuthProvider,
98
DatabricksOAuthProvider,
109
)
@@ -13,16 +12,14 @@
1312
class AuthType(Enum):
1413
DATABRICKS_OAUTH = "databricks-oauth"
1514
AZURE_OAUTH = "azure-oauth"
16-
# other supported types (access_token, user/pass) can be inferred
15+
# other supported types (access_token) can be inferred
1716
# we can add more types as needed later
1817

1918

2019
class ClientContext:
2120
def __init__(
2221
self,
2322
hostname: str,
24-
username: Optional[str] = None,
25-
password: Optional[str] = None,
2623
access_token: Optional[str] = None,
2724
auth_type: Optional[str] = None,
2825
oauth_scopes: Optional[List[str]] = None,
@@ -34,8 +31,6 @@ def __init__(
3431
credentials_provider=None,
3532
):
3633
self.hostname = hostname
37-
self.username = username
38-
self.password = password
3934
self.access_token = access_token
4035
self.auth_type = auth_type
4136
self.oauth_scopes = oauth_scopes
@@ -65,8 +60,6 @@ def get_auth_provider(cfg: ClientContext):
6560
)
6661
elif cfg.access_token is not None:
6762
return AccessTokenAuthProvider(cfg.access_token)
68-
elif cfg.username is not None and cfg.password is not None:
69-
return BasicAuthProvider(cfg.username, cfg.password)
7063
elif cfg.use_cert_as_auth and cfg.tls_client_cert_file:
7164
# no op authenticator. authentication is performed using ssl certificate outside of headers
7265
return AuthProvider()
@@ -100,12 +93,16 @@ def get_python_sql_connector_auth_provider(hostname: str, **kwargs):
10093
(client_id, redirect_port_range) = get_client_id_and_redirect_port(
10194
auth_type == AuthType.AZURE_OAUTH.value
10295
)
96+
if kwargs.get("username") or kwargs.get("password"):
97+
raise ValueError(
98+
"Username/password authentication is no longer supported. "
99+
"Please use OAuth or access token instead."
100+
)
101+
103102
cfg = ClientContext(
104103
hostname=normalize_host_name(hostname),
105104
auth_type=auth_type,
106105
access_token=kwargs.get("access_token"),
107-
username=kwargs.get("_username"),
108-
password=kwargs.get("_password"),
109106
use_cert_as_auth=kwargs.get("_use_cert_as_auth"),
110107
tls_client_cert_file=kwargs.get("_tls_client_cert_file"),
111108
oauth_scopes=PYSQL_OAUTH_SCOPES,

src/databricks/sql/auth/authenticators.py

-15
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,6 @@ def add_headers(self, request_headers: Dict[str, str]):
4343
request_headers["Authorization"] = self.__authorization_header_value
4444

4545

46-
# Private API: this is an evolving interface and it will change in the future.
47-
# Please must not depend on it in your applications.
48-
class BasicAuthProvider(AuthProvider):
49-
def __init__(self, username: str, password: str):
50-
auth_credentials = f"{username}:{password}".encode("UTF-8")
51-
auth_credentials_base64 = base64.standard_b64encode(auth_credentials).decode(
52-
"UTF-8"
53-
)
54-
55-
self.__authorization_header_value = f"Basic {auth_credentials_base64}"
56-
57-
def add_headers(self, request_headers: Dict[str, str]):
58-
request_headers["Authorization"] = self.__authorization_header_value
59-
60-
6146
# Private API: this is an evolving interface and it will change in the future.
6247
# Please must not depend on it in your applications.
6348
class DatabricksOAuthProvider(AuthProvider):

src/databricks/sql/client.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,8 @@ def read(self) -> Optional[OAuthToken]:
163163
# Internal arguments in **kwargs:
164164
# _user_agent_entry
165165
# Tag to add to User-Agent header. For use by partners.
166-
# _username, _password
167-
# Username and password Basic authentication (no official support)
168166
# _use_cert_as_auth
169-
# Use a TLS cert instead of a token or username / password (internal use only)
167+
# Use a TLS cert instead of a token
170168
# _enable_ssl
171169
# Connect over HTTP instead of HTTPS
172170
# _port

tests/unit/test_auth.py

+9-31
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
from databricks.sql.auth.auth import (
77
AccessTokenAuthProvider,
8-
BasicAuthProvider,
98
AuthProvider,
109
ExternalAuthProvider,
1110
AuthType,
@@ -33,21 +32,6 @@ def test_access_token_provider(self):
3332
self.assertEqual(len(http_request.keys()), 2)
3433
self.assertEqual(http_request["myKey"], "myVal")
3534

36-
def test_basic_auth_provider(self):
37-
username = "moderakh"
38-
password = "Elevate Databricks 123!!!"
39-
auth = BasicAuthProvider(username=username, password=password)
40-
41-
http_request = {"myKey": "myVal"}
42-
auth.add_headers(http_request)
43-
44-
self.assertEqual(
45-
http_request["Authorization"],
46-
"Basic bW9kZXJha2g6RWxldmF0ZSBEYXRhYnJpY2tzIDEyMyEhIQ==",
47-
)
48-
self.assertEqual(len(http_request.keys()), 2)
49-
self.assertEqual(http_request["myKey"], "myVal")
50-
5135
def test_noop_auth_provider(self):
5236
auth = AuthProvider()
5337

@@ -175,21 +159,6 @@ def __call__(self, *args, **kwargs) -> HeaderFactory:
175159
auth_provider.add_headers(headers)
176160
self.assertEqual(headers["foo"], "bar")
177161

178-
def test_get_python_sql_connector_auth_provider_username_password(self):
179-
username = "moderakh"
180-
password = "Elevate Databricks 123!!!"
181-
hostname = "moderakh-test.cloud.databricks.com"
182-
kwargs = {"_username": username, "_password": password}
183-
auth_provider = get_python_sql_connector_auth_provider(hostname, **kwargs)
184-
self.assertTrue(type(auth_provider).__name__, "BasicAuthProvider")
185-
186-
headers = {}
187-
auth_provider.add_headers(headers)
188-
self.assertEqual(
189-
headers["Authorization"],
190-
"Basic bW9kZXJha2g6RWxldmF0ZSBEYXRhYnJpY2tzIDEyMyEhIQ==",
191-
)
192-
193162
def test_get_python_sql_connector_auth_provider_noop(self):
194163
tls_client_cert_file = "fake.cert"
195164
use_cert_as_auth = "abc"
@@ -200,3 +169,12 @@ def test_get_python_sql_connector_auth_provider_noop(self):
200169
}
201170
auth_provider = get_python_sql_connector_auth_provider(hostname, **kwargs)
202171
self.assertTrue(type(auth_provider).__name__, "CredentialProvider")
172+
173+
def test_get_python_sql_connector_basic_auth(self):
174+
kwargs = {
175+
"username": "username",
176+
"password": "password",
177+
}
178+
with self.assertRaises(ValueError) as e:
179+
get_python_sql_connector_auth_provider("foo.cloud.databricks.com", **kwargs)
180+
self.assertIn("Username/password authentication is no longer supported", str(e.exception))

tests/unit/test_client.py

-8
Original file line numberDiff line numberDiff line change
@@ -103,21 +103,13 @@ def test_close_uses_the_correct_session_id(self, mock_client_class):
103103
def test_auth_args(self, mock_client_class):
104104
# Test that the following auth args work:
105105
# token = foo,
106-
# token = None, _username = foo, _password = bar
107106
# token = None, _tls_client_cert_file = something, _use_cert_as_auth = True
108107
connection_args = [
109108
{
110109
"server_hostname": "foo",
111110
"http_path": None,
112111
"access_token": "tok",
113112
},
114-
{
115-
"server_hostname": "foo",
116-
"http_path": None,
117-
"_username": "foo",
118-
"_password": "bar",
119-
"access_token": None,
120-
},
121113
{
122114
"server_hostname": "foo",
123115
"http_path": None,

tests/unit/test_oauth_persistence.py

-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11

22
import unittest
33

4-
from databricks.sql.auth.auth import AccessTokenAuthProvider, BasicAuthProvider, AuthProvider
5-
from databricks.sql.auth.auth import get_python_sql_connector_auth_provider
64
from databricks.sql.experimental.oauth_persistence import DevOnlyFilePersistence, OAuthToken
75
import tempfile
86
import os

0 commit comments

Comments
 (0)