Skip to content

Commit b2c73f8

Browse files
Apply #2182 to async code
adjust no_auth usage for async
1 parent 9b7954b commit b2c73f8

File tree

5 files changed

+109
-0
lines changed

5 files changed

+109
-0
lines changed

src/snowflake/connector/aio/auth/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from ._default import AuthByDefault
1111
from ._idtoken import AuthByIdToken
1212
from ._keypair import AuthByKeyPair
13+
from ._no_auth import AuthNoAuth
1314
from ._oauth import AuthByOAuth
1415
from ._okta import AuthByOkta
1516
from ._pat import AuthByPAT
@@ -26,6 +27,7 @@
2627
AuthByWebBrowser,
2728
AuthByIdToken,
2829
AuthByPAT,
30+
AuthNoAuth,
2931
)
3032
)
3133

@@ -38,6 +40,7 @@
3840
"AuthByOkta",
3941
"AuthByUsrPwdMfa",
4042
"AuthByWebBrowser",
43+
"AuthNoAuth",
4144
"Auth",
4245
"AuthType",
4346
"FIRST_PARTY_AUTHENTICATORS",

src/snowflake/connector/aio/auth/_auth.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
ReauthenticationRequest,
4444
)
4545
from ...sqlstate import SQLSTATE_CONNECTION_WAS_NOT_ESTABLISHED
46+
from ._no_auth import AuthNoAuth
4647

4748
if TYPE_CHECKING:
4849
from ._by_plugin import AuthByPlugin
@@ -76,6 +77,10 @@ async def authenticate(
7677
)
7778
logger.debug("authenticate")
7879

80+
# For no-auth connection, authentication is no-op, and we can return early here.
81+
if isinstance(auth_instance, AuthNoAuth):
82+
return {}
83+
7984
if timeout is None:
8085
timeout = auth_instance.timeout
8186

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env python
2+
#
3+
# Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved.
4+
#
5+
6+
from __future__ import annotations
7+
8+
from typing import Any
9+
10+
from ...auth.no_auth import AuthNoAuth as AuthNoAuthSync
11+
from ._by_plugin import AuthByPlugin as AuthByPluginAsync
12+
13+
14+
class AuthNoAuth(AuthByPluginAsync, AuthNoAuthSync):
15+
"""No-auth Authentication.
16+
17+
It is a dummy auth that requires no extra connection establishment.
18+
"""
19+
20+
def __init__(self, **kwargs) -> None:
21+
AuthNoAuthSync.__init__(self, **kwargs)
22+
23+
async def reset_secrets(self) -> None:
24+
AuthNoAuthSync.reset_secrets(self)
25+
26+
async def prepare(self, **kwargs: Any) -> None:
27+
AuthNoAuthSync.prepare(self, **kwargs)
28+
29+
async def reauthenticate(self, **kwargs: Any) -> dict[str, bool]:
30+
return AuthNoAuthSync.reauthenticate(self, **kwargs)
31+
32+
async def update_body(self, body: dict[Any, Any]) -> None:
33+
AuthNoAuthSync.update_body(self, body)

test/integ/aio/test_connection_async.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,3 +1659,30 @@ async def test_is_valid(conn_cnx):
16591659
assert conn
16601660
assert await conn.is_valid() is True
16611661
assert await conn.is_valid() is False
1662+
1663+
1664+
async def test_no_auth_connection_negative_case():
1665+
# AuthNoAuth does not exist in old drivers, so we import at test level to
1666+
# skip importing it for old driver tests.
1667+
from test.integ.aio.conftest import create_connection
1668+
1669+
from snowflake.connector.aio.auth._no_auth import AuthNoAuth
1670+
1671+
no_auth = AuthNoAuth()
1672+
1673+
# Create a no-auth connection in an invalid way.
1674+
# We do not fail connection establishment because there is no validated way
1675+
# to tell whether the no-auth is a valid use case or not. But it is
1676+
# effectively protected because invalid no-auth will fail to run any query.
1677+
conn = await create_connection("default", auth_class=no_auth)
1678+
1679+
# Make sure we are indeed passing the no-auth configuration to the
1680+
# connection.
1681+
assert isinstance(conn.auth_class, AuthNoAuth)
1682+
1683+
# We expect a failure here when executing queries, because invalid no-auth
1684+
# connection is not able to run any query
1685+
with pytest.raises(DatabaseError, match="Connection is closed"):
1686+
await conn.execute_string("select 1")
1687+
1688+
await conn.close()
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env python
2+
#
3+
# Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved.
4+
#
5+
6+
from __future__ import annotations
7+
8+
import pytest
9+
10+
11+
@pytest.mark.skipolddriver
12+
async def test_auth_no_auth():
13+
"""Simple test for AuthNoAuth."""
14+
15+
# AuthNoAuth does not exist in old drivers, so we import at test level to
16+
# skip importing it for old driver tests.
17+
from snowflake.connector.aio.auth._no_auth import AuthNoAuth
18+
19+
auth = AuthNoAuth()
20+
21+
body = {"data": {}}
22+
old_body = body.copy() # Make a copy to compare against
23+
await auth.update_body(body)
24+
# update_body should be no-op for NO_AUTH, therefore the body content should remain the same.
25+
assert body == old_body, f"body is {body}, old_body is {old_body}"
26+
27+
# assertion_content should always return None in NO_AUTH.
28+
assert auth.assertion_content is None, auth.assertion_content
29+
30+
# reauthenticate should always return success.
31+
expected_reauth_response = {"success": True}
32+
reauth_response = await auth.reauthenticate()
33+
assert (
34+
reauth_response == expected_reauth_response
35+
), f"reauthenticate() is expected to return {expected_reauth_response}, but returns {reauth_response}"
36+
37+
# It also returns success response even if we pass extra keyword argument(s).
38+
reauth_response = await auth.reauthenticate(foo="bar")
39+
assert (
40+
reauth_response == expected_reauth_response
41+
), f'reauthenticate(foo="bar") is expected to return {expected_reauth_response}, but returns {reauth_response}'

0 commit comments

Comments
 (0)