Skip to content

Commit 5b08b27

Browse files
feat: Add Core connection validation and refactor _determine_auth
- Refactor _determine_auth to accept URL object directly - Add validation for Core connections to reject engine_name, account_name, and credentials - Update existing Core connection tests to use valid format - Add comprehensive tests for Core connection validation errors - Addresses GitHub PR comments for stricter Core connection handling Co-Authored-By: [email protected] <[email protected]>
1 parent 15dad9f commit 5b08b27

File tree

2 files changed

+64
-14
lines changed

2 files changed

+64
-14
lines changed

src/firebolt_db/firebolt_dialect.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,22 @@ def create_connect_args(self, url: URL) -> Tuple[List, Dict]:
162162
# bool flag to boolean for SDK compatibility
163163
token_cache_flag = bool(strtobool(parameters.pop("use_token_cache", "True")))
164164

165+
# Validate Core connection parameters
165166
if is_core_connection:
166-
auth = _determine_auth("", "", token_cache_flag, is_core=True)
167-
else:
168-
auth = _determine_auth(url.username, url.password, token_cache_flag)
167+
if url.username or url.password:
168+
raise ArgumentError(
169+
"Core connections do not support username/password authentication"
170+
)
171+
if url.database:
172+
raise ArgumentError(
173+
"Core connections do not support engine_name parameter"
174+
)
175+
if "account_name" in parameters:
176+
raise ArgumentError(
177+
"Core connections do not support account_name parameter"
178+
)
179+
180+
auth = _determine_auth(url, token_cache_flag)
169181

170182
kwargs: Dict[str, Union[str, Auth, Dict[str, Any], None]] = {
171183
"database": url.host or None,
@@ -386,12 +398,13 @@ def get_is_nullable(column_is_nullable: int) -> bool:
386398
return column_is_nullable == 1
387399

388400

389-
def _determine_auth(
390-
key: str, secret: str, token_cache_flag: bool = True, is_core: bool = False
391-
) -> Auth:
392-
if is_core:
401+
def _determine_auth(url: URL, token_cache_flag: bool = True) -> Auth:
402+
parameters = dict(url.query)
403+
is_core_connection = "url" in parameters
404+
405+
if is_core_connection:
393406
return FireboltCore()
394-
elif "@" in key:
395-
return UsernamePassword(key, secret, token_cache_flag)
407+
elif "@" in (url.username or ""):
408+
return UsernamePassword(url.username, url.password, token_cache_flag)
396409
else:
397-
return ClientCredentials(key, secret, token_cache_flag)
410+
return ClientCredentials(url.username, url.password, token_cache_flag)

tests/unit/test_firebolt_dialect.py

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,13 +304,11 @@ def test_unicode_description(
304304
assert dialect._check_unicode_description(connection)
305305

306306
def test_create_connect_args_core_connection(self, dialect: FireboltDialect):
307-
connection_url = (
308-
"test_engine://test_db_name/test_engine_name?" "url=http://localhost:8080"
309-
)
307+
connection_url = "test_engine://test_db_name?url=http://localhost:8080"
310308
u = url.make_url(connection_url)
311309
result_list, result_dict = dialect.create_connect_args(u)
312310

313-
assert result_dict["engine_name"] == "test_engine_name"
311+
assert result_dict["engine_name"] is None
314312
assert result_dict["database"] == "test_db_name"
315313
assert result_dict["url"] == "http://localhost:8080"
316314
assert isinstance(result_dict["auth"], FireboltCore)
@@ -340,6 +338,45 @@ def test_create_connect_args_core_no_credentials_required(
340338
assert isinstance(result_dict["auth"], FireboltCore)
341339
assert "account_name" not in result_dict
342340

341+
def test_create_connect_args_core_with_credentials_error(
342+
self, dialect: FireboltDialect
343+
):
344+
connection_url = (
345+
"test_engine://user:pass@test_db_name?url=http://localhost:8080"
346+
)
347+
u = url.make_url(connection_url)
348+
349+
with raises(
350+
ArgumentError,
351+
match="Core connections do not support username/password authentication",
352+
):
353+
dialect.create_connect_args(u)
354+
355+
def test_create_connect_args_core_with_engine_error(self, dialect: FireboltDialect):
356+
connection_url = (
357+
"test_engine://test_db_name/test_engine?url=http://localhost:8080"
358+
)
359+
u = url.make_url(connection_url)
360+
361+
with raises(
362+
ArgumentError, match="Core connections do not support engine_name parameter"
363+
):
364+
dialect.create_connect_args(u)
365+
366+
def test_create_connect_args_core_with_account_error(
367+
self, dialect: FireboltDialect
368+
):
369+
connection_url = (
370+
"test_engine://test_db_name?url=http://localhost:8080&account_name=test"
371+
)
372+
u = url.make_url(connection_url)
373+
374+
with raises(
375+
ArgumentError,
376+
match="Core connections do not support account_name parameter",
377+
):
378+
dialect.create_connect_args(u)
379+
343380

344381
def test_get_is_nullable():
345382
assert firebolt_db.firebolt_dialect.get_is_nullable(1)

0 commit comments

Comments
 (0)