feat: Support OAuth2 single-use refresh tokens (#38364)

This commit is contained in:
Vitor Avila
2026-03-03 16:07:15 -03:00
committed by GitHub
parent 2ab9d37a00
commit fa34609952
4 changed files with 157 additions and 0 deletions

View File

@@ -188,6 +188,62 @@ def test_refresh_oauth2_token_no_access_token_in_response(
assert result is None
def test_refresh_oauth2_token_updates_refresh_token(
mocker: MockerFixture,
) -> None:
"""
Test that refresh_oauth2_token updates the refresh token when a new one is returned.
Some OAuth2 providers issue single-use refresh tokens, where each token refresh
response includes a new refresh token that replaces the previous one.
"""
db = mocker.patch("superset.utils.oauth2.db")
mocker.patch("superset.utils.oauth2.DistributedLock")
db_engine_spec = mocker.MagicMock()
db_engine_spec.get_oauth2_fresh_token.return_value = {
"access_token": "new-access-token",
"expires_in": 3600,
"refresh_token": "new-refresh-token",
}
token = mocker.MagicMock()
token.refresh_token = "old-refresh-token" # noqa: S105
with freeze_time("2024-01-01"):
refresh_oauth2_token(DUMMY_OAUTH2_CONFIG, 1, 1, db_engine_spec, token)
assert token.access_token == "new-access-token" # noqa: S105
assert token.access_token_expiration == datetime(2024, 1, 1, 1)
assert token.refresh_token == "new-refresh-token" # noqa: S105
db.session.add.assert_called_with(token)
def test_refresh_oauth2_token_keeps_refresh_token(
mocker: MockerFixture,
) -> None:
"""
Test that refresh_oauth2_token keeps the existing refresh token when none returned.
When the OAuth2 provider does not issue a new refresh token in the response,
the original refresh token should be preserved.
"""
db = mocker.patch("superset.utils.oauth2.db")
mocker.patch("superset.utils.oauth2.DistributedLock")
db_engine_spec = mocker.MagicMock()
db_engine_spec.get_oauth2_fresh_token.return_value = {
"access_token": "new-access-token",
"expires_in": 3600,
}
token = mocker.MagicMock()
token.refresh_token = "original-refresh-token" # noqa: S105
with freeze_time("2024-01-01"):
refresh_oauth2_token(DUMMY_OAUTH2_CONFIG, 1, 1, db_engine_spec, token)
assert token.access_token == "new-access-token" # noqa: S105
assert token.refresh_token == "original-refresh-token" # noqa: S105
db.session.add.assert_called_with(token)
def test_generate_code_verifier_length() -> None:
"""
Test that generate_code_verifier produces a string of valid length (RFC 7636).