Skip to content

Commit fd574d3

Browse files
SNOW-2068668 Move OAuth out of PrPr flag (#2301)
1 parent 60493f3 commit fd574d3

File tree

3 files changed

+13
-62
lines changed

3 files changed

+13
-62
lines changed

DESCRIPTION.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,16 @@ Source code is also available at: https://github.com/snowflakedb/snowflake-conne
88

99
# Release Notes
1010
- v3.15(TBD)
11-
- Bumped up min boto and botocore version to 1.24
12-
- OCSP: terminate certificates chain traversal if a trusted certificate already reached
11+
- Bumped up min boto and botocore version to 1.24.
12+
- OCSP: terminate certificates chain traversal if a trusted certificate already reached.
13+
- Added new authentication methods support for programmatic access tokens (PATs), OAuth 2.0 Authorization Code Flow, OAuth 2.0 Client Credentials Flow, and OAuth Token caching.
14+
- For OAuth 2.0 Authorization Code Flow:
15+
- Added the `oauth_client_id`, `oauth_client_secret`, `oauth_authorization_url`, `oauth_token_request_url`, `oauth_redirect_uri`, `oauth_scope`, `oauth_disable_pkce`, `oauth_enable_refresh_tokens` and `oauth_enable_single_use_refresh_tokens` parameters.
16+
- Added the `OAUTH_AUTHORIZATION_CODE` value for the parameter authenticator.
17+
- For OAuth 2.0 Client Credentials Flow:
18+
- Added the `oauth_client_id`, `oauth_client_secret`, `oauth_token_request_url`, and `oauth_scope` parameters.
19+
- Added the `OAUTH_CLIENT_CREDENTIALS` value for the parameter authenticator.
20+
- For OAuth Token caching: Passing a username to driver configuration is required, and the `client_store_temporary_credential property` is to be set to `true`.
1321

1422
- v3.14.1(April 21, 2025)
1523
- Added support for Python 3.13.

src/snowflake/connector/connection.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,8 @@ def _get_private_bytes_from_file(
346346
str,
347347
# SNOW-1825621: OAUTH implementation
348348
),
349-
"oauth_enable_pkce": (
350-
True,
349+
"oauth_disable_pkce": (
350+
False,
351351
bool,
352352
# SNOW-1825621: OAUTH PKCE
353353
),
@@ -1204,7 +1204,6 @@ def __open_connection(self):
12041204
backoff_generator=self._backoff_generator,
12051205
)
12061206
elif self._authenticator == OAUTH_AUTHORIZATION_CODE:
1207-
self._check_experimental_authentication_flag()
12081207
self._check_oauth_parameters()
12091208
if self._role and (self._oauth_scope == ""):
12101209
# if role is known then let's inject it into scope
@@ -1221,7 +1220,7 @@ def __open_connection(self):
12211220
),
12221221
redirect_uri=self._oauth_redirect_uri,
12231222
scope=self._oauth_scope,
1224-
pkce_enabled=self._oauth_enable_pkce,
1223+
pkce_enabled=not self._oauth_disable_pkce,
12251224
token_cache=(
12261225
auth.get_token_cache()
12271226
if self._client_store_temporary_credential
@@ -1232,7 +1231,6 @@ def __open_connection(self):
12321231
enable_single_use_refresh_tokens=self._oauth_enable_single_use_refresh_tokens,
12331232
)
12341233
elif self._authenticator == OAUTH_CLIENT_CREDENTIALS:
1235-
self._check_experimental_authentication_flag()
12361234
self._check_oauth_parameters()
12371235
if self._role and (self._oauth_scope == ""):
12381236
# if role is known then let's inject it into scope

test/unit/test_oauth_token.py

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ def test_oauth_code_successful_flow(
138138
monkeypatch,
139139
omit_oauth_urls_check,
140140
) -> None:
141-
monkeypatch.setenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", "true")
142141
monkeypatch.setenv("SNOWFLAKE_AUTH_SOCKET_REUSE_PORT", "true")
143142

144143
wiremock_client.import_mapping(
@@ -181,7 +180,6 @@ def test_oauth_code_invalid_state(
181180
monkeypatch,
182181
omit_oauth_urls_check,
183182
) -> None:
184-
monkeypatch.setenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", "true")
185183
monkeypatch.setenv("SNOWFLAKE_AUTH_SOCKET_REUSE_PORT", "true")
186184

187185
wiremock_client.import_mapping(
@@ -217,7 +215,6 @@ def test_oauth_code_scope_error(
217215
webbrowser_mock,
218216
monkeypatch,
219217
) -> None:
220-
monkeypatch.setenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", "true")
221218
monkeypatch.setenv("SNOWFLAKE_AUTH_SOCKET_REUSE_PORT", "true")
222219

223220
wiremock_client.import_mapping(
@@ -254,7 +251,6 @@ def test_oauth_code_token_request_error(
254251
monkeypatch,
255252
omit_oauth_urls_check,
256253
) -> None:
257-
monkeypatch.setenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", "true")
258254
monkeypatch.setenv("SNOWFLAKE_AUTH_SOCKET_REUSE_PORT", "true")
259255

260256
with WiremockClient() as wiremock_client:
@@ -293,7 +289,6 @@ def test_oauth_code_browser_timeout(
293289
monkeypatch,
294290
omit_oauth_urls_check,
295291
) -> None:
296-
monkeypatch.setenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", "true")
297292
monkeypatch.setenv("SNOWFLAKE_AUTH_SOCKET_REUSE_PORT", "true")
298293

299294
wiremock_client.import_mapping(
@@ -335,7 +330,6 @@ def test_oauth_code_custom_urls(
335330
monkeypatch,
336331
omit_oauth_urls_check,
337332
) -> None:
338-
monkeypatch.setenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", "true")
339333
monkeypatch.setenv("SNOWFLAKE_AUTH_SOCKET_REUSE_PORT", "true")
340334

341335
wiremock_client.import_mapping(
@@ -379,7 +373,6 @@ def test_oauth_code_successful_refresh_token_flow(
379373
temp_cache,
380374
omit_oauth_urls_check,
381375
) -> None:
382-
monkeypatch.setenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", "true")
383376
monkeypatch.setenv("SNOWFLAKE_AUTH_SOCKET_REUSE_PORT", "true")
384377

385378
wiremock_client.import_mapping(
@@ -440,7 +433,6 @@ def test_oauth_code_expired_refresh_token_flow(
440433
temp_cache,
441434
omit_oauth_urls_check,
442435
) -> None:
443-
monkeypatch.setenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", "true")
444436
monkeypatch.setenv("SNOWFLAKE_AUTH_SOCKET_REUSE_PORT", "true")
445437

446438
wiremock_client.import_mapping(
@@ -522,7 +514,6 @@ def test_client_creds_successful_flow(
522514
wiremock_generic_mappings_dir,
523515
monkeypatch,
524516
) -> None:
525-
monkeypatch.setenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", "true")
526517
wiremock_client.import_mapping(
527518
wiremock_oauth_client_creds_dir / "successful_flow.json"
528519
)
@@ -557,7 +548,6 @@ def test_client_creds_token_request_error(
557548
wiremock_generic_mappings_dir,
558549
monkeypatch,
559550
) -> None:
560-
monkeypatch.setenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", "true")
561551
wiremock_client.import_mapping(
562552
wiremock_oauth_client_creds_dir / "token_request_error.json"
563553
)
@@ -597,8 +587,6 @@ def test_client_creds_successful_refresh_token_flow(
597587
monkeypatch,
598588
temp_cache,
599589
) -> None:
600-
monkeypatch.setenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", "true")
601-
602590
wiremock_client.import_mapping(
603591
wiremock_generic_mappings_dir / "snowflake_login_failed.json"
604592
)
@@ -653,8 +641,6 @@ def test_client_creds_expired_refresh_token_flow(
653641
monkeypatch,
654642
temp_cache,
655643
) -> None:
656-
monkeypatch.setenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", "true")
657-
658644
wiremock_client.import_mapping(
659645
wiremock_generic_mappings_dir / "snowflake_login_failed.json"
660646
)
@@ -701,44 +687,3 @@ def test_client_creds_expired_refresh_token_flow(
701687
new_refresh_token = temp_cache.retrieve(refresh_token_key)
702688
assert new_access_token == "access-token-123"
703689
assert new_refresh_token == "refresh-token-123"
704-
705-
706-
@pytest.mark.skipolddriver
707-
@pytest.mark.parametrize(
708-
"authenticator", ["OAUTH_AUTHORIZATION_CODE", "OAUTH_CLIENT_CREDENTIALS"]
709-
)
710-
def test_auth_is_experimental(
711-
authenticator,
712-
monkeypatch,
713-
) -> None:
714-
monkeypatch.delenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", False)
715-
with pytest.raises(
716-
snowflake.connector.ProgrammingError,
717-
match=r"SF_ENABLE_EXPERIMENTAL_AUTHENTICATION",
718-
):
719-
snowflake.connector.connect(
720-
user="testUser",
721-
account="testAccount",
722-
authenticator=authenticator,
723-
)
724-
725-
726-
@pytest.mark.skipolddriver
727-
@pytest.mark.skipolddriver
728-
@pytest.mark.parametrize(
729-
"authenticator", ["OAUTH_AUTHORIZATION_CODE", "OAUTH_CLIENT_CREDENTIALS"]
730-
)
731-
def test_auth_experimental_when_variable_set_to_false(
732-
authenticator,
733-
monkeypatch,
734-
) -> None:
735-
monkeypatch.setenv("SF_ENABLE_EXPERIMENTAL_AUTHENTICATION", "false")
736-
with pytest.raises(
737-
snowflake.connector.ProgrammingError,
738-
match=r"SF_ENABLE_EXPERIMENTAL_AUTHENTICATION",
739-
):
740-
snowflake.connector.connect(
741-
user="testUser",
742-
account="testAccount",
743-
authenticator="OAUTH_CLIENT_CREDENTIALS",
744-
)

0 commit comments

Comments
 (0)