You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2026/04/20 22:08:41 UTC
(superset) branch master updated: fix(oauth2): silence lock acquisition errors on token refresh (#39463)
This is an automated email from the ASF dual-hosted git repository.
betodealmeida pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 5fb89b865da fix(oauth2): silence lock acquisition errors on token refresh (#39463)
5fb89b865da is described below
commit 5fb89b865da5ce2f5736a84e9de41a2d33e2ade4
Author: Beto Dealmeida <ro...@dealmeida.net>
AuthorDate: Mon Apr 20 18:08:33 2026 -0400
fix(oauth2): silence lock acquisition errors on token refresh (#39463)
Co-authored-by: Beto Dealmeida <be...@preset.io>
---
superset/utils/oauth2.py | 2 ++
tests/unit_tests/utils/oauth2_tests.py | 39 ++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+)
diff --git a/superset/utils/oauth2.py b/superset/utils/oauth2.py
index 76b671b4109..62e6559a1b6 100644
--- a/superset/utils/oauth2.py
+++ b/superset/utils/oauth2.py
@@ -82,6 +82,8 @@ def generate_code_challenge(code_verifier: str) -> str:
factor=10,
base=2,
max_tries=5,
+ raise_on_giveup=False,
+ giveup_log_level=logging.DEBUG,
)
def get_oauth2_access_token(
config: OAuth2ClientConfig,
diff --git a/tests/unit_tests/utils/oauth2_tests.py b/tests/unit_tests/utils/oauth2_tests.py
index a320a8a23e8..1ca9a4eb21b 100644
--- a/tests/unit_tests/utils/oauth2_tests.py
+++ b/tests/unit_tests/utils/oauth2_tests.py
@@ -338,6 +338,45 @@ def test_encode_decode_oauth2_state(
assert decoded["user_id"] == 2
+def test_get_oauth2_access_token_lock_not_acquired_no_error_log(
+ mocker: MockerFixture,
+ caplog: pytest.LogCaptureFixture,
+) -> None:
+ """
+ Test that when a distributed lock can't be acquired, no error is logged and
+ the function returns None instead of raising.
+
+ This scenario occurs when a dashboard with multiple charts from the same
+ OAuth2-enabled DB has an expired token: simultaneous requests compete for
+ the lock, and only the first one wins. The rest should silently return None.
+ """
+ import logging
+
+ from superset.exceptions import AcquireDistributedLockFailedException
+
+ mocker.patch("time.sleep") # avoid backoff delays in tests
+
+ db = mocker.patch("superset.utils.oauth2.db")
+ db_engine_spec = mocker.MagicMock()
+ token = mocker.MagicMock()
+ token.access_token = "access-token" # noqa: S105
+ token.access_token_expiration = datetime(2024, 1, 1)
+ token.refresh_token = "refresh-token" # noqa: S105
+ db.session.query().filter_by().one_or_none.return_value = token
+
+ mocker.patch(
+ "superset.utils.oauth2.refresh_oauth2_token",
+ side_effect=AcquireDistributedLockFailedException("Lock not available"),
+ )
+
+ with freeze_time("2024-01-02"):
+ with caplog.at_level(logging.DEBUG):
+ result = get_oauth2_access_token({}, 1, 1, db_engine_spec)
+
+ assert result is None
+ assert not any(record.levelno >= logging.ERROR for record in caplog.records)
+
+
def test_get_oauth2_redirect_uri_from_config(mocker: MockerFixture) -> None:
"""
Test that get_oauth2_redirect_uri returns the configured value when set.