Skip to content

Commit 19f5415

Browse files
authored
fix: snowflake authenticator matching is not case sensitive (#772)
1 parent f6cd955 commit 19f5415

3 files changed

Lines changed: 51 additions & 2 deletions

File tree

docs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
- `pyproject.toml` can now be supplied via `--requirements-file` for deploy and
1111
write-manifest.
12+
- Perform case insensitive matching of the configured Snowflake connection authenticator.
1213

1314
## [1.29.0] - 2026-04-29
1415

rsconnect/api.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,11 @@ def fmt_payload(self):
274274
raise RSConnectException("No Snowflake connection found.")
275275

276276
authenticator = params.get("authenticator")
277-
if authenticator == "SNOWFLAKE_JWT":
277+
if not authenticator:
278+
raise NotImplementedError("Snowflake connection does not declare an authenticator.")
279+
280+
authenticator = authenticator.lower()
281+
if authenticator == "snowflake_jwt":
278282
spcs_url = urlparse(self.url)
279283
scope = f"session:role:{params['role']} {spcs_url.netloc}" if params.get("role") else spcs_url.netloc
280284
jwt = generate_jwt(self.snowflake_connection_name)

tests/test_api.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ def test_token_endpoint_with_none_params(self, mock_get_parameters):
293293
server.token_endpoint()
294294

295295
@patch("rsconnect.api.get_parameters")
296-
def test_fmt_payload(self, mock_get_parameters):
296+
def test_fmt_payload_jwt_uppercase(self, mock_get_parameters):
297297
server = SPCSConnectServer("https://spcs.example.com", "test-api-key", "example_connection")
298298
mock_get_parameters.return_value = {
299299
"account": "test_account",
@@ -315,6 +315,50 @@ def test_fmt_payload(self, mock_get_parameters):
315315
mock_get_parameters.assert_called_once_with("example_connection")
316316
mock_generate_jwt.assert_called_once_with("example_connection")
317317

318+
@patch("rsconnect.api.get_parameters")
319+
def test_fmt_payload_jwt_lowercase(self, mock_get_parameters):
320+
server = SPCSConnectServer("https://spcs.example.com", "test-api-key", "example_connection")
321+
mock_get_parameters.return_value = {
322+
"account": "test_account",
323+
"role": "test_role",
324+
"authenticator": "snowflake_jwt",
325+
}
326+
327+
with patch("rsconnect.api.generate_jwt") as mock_generate_jwt:
328+
mock_generate_jwt.return_value = "mocked_jwt"
329+
payload = server.fmt_payload()
330+
331+
assert (
332+
payload["body"]
333+
== "scope=session%3Arole%3Atest_role+spcs.example.com&assertion=mocked_jwt&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer" # noqa
334+
)
335+
assert payload["headers"] == {"Content-Type": "application/x-www-form-urlencoded"}
336+
assert payload["path"] == "/oauth/token"
337+
338+
mock_get_parameters.assert_called_once_with("example_connection")
339+
mock_generate_jwt.assert_called_once_with("example_connection")
340+
341+
@patch("rsconnect.api.get_parameters")
342+
def test_fmt_payload_with_unsupported_authenticator(self, mock_get_parameters):
343+
server = SPCSConnectServer("https://spcs.example.com", "test-api-key", "example_connection")
344+
mock_get_parameters.return_value = {
345+
"account": "test_account",
346+
"role": "test_role",
347+
"authenticator": "unrecognized",
348+
}
349+
with pytest.raises(NotImplementedError, match="Unsupported authenticator for SPCS Connect: unrecognized"):
350+
server.fmt_payload()
351+
352+
@patch("rsconnect.api.get_parameters")
353+
def test_fmt_payload_with_no_authenticator(self, mock_get_parameters):
354+
server = SPCSConnectServer("https://spcs.example.com", "test-api-key", "example_connection")
355+
mock_get_parameters.return_value = {
356+
"account": "test_account",
357+
"role": "test_role",
358+
}
359+
with pytest.raises(NotImplementedError, match="Snowflake connection does not declare an authenticator."):
360+
server.fmt_payload()
361+
318362
@patch("rsconnect.api.get_parameters")
319363
def test_fmt_payload_with_none_params(self, mock_get_parameters):
320364
server = SPCSConnectServer("https://spcs.example.com", "test-api-key", "example_connection")

0 commit comments

Comments
 (0)