fix(mcp): handle OAuth-authenticated databases in execute_sql (#39166)

This commit is contained in:
Amin Ghadersohi
2026-04-09 15:47:00 -04:00
committed by GitHub
parent 5815665cc6
commit 68067d7f44
14 changed files with 452 additions and 18 deletions

View File

@@ -33,6 +33,7 @@ from superset.utils.oauth2 import (
generate_code_challenge,
generate_code_verifier,
get_oauth2_access_token,
get_oauth2_redirect_uri,
refresh_oauth2_token,
)
@@ -335,3 +336,66 @@ def test_encode_decode_oauth2_state(
assert "code_verifier" not in decoded
assert decoded["database_id"] == 1
assert decoded["user_id"] == 2
def test_get_oauth2_redirect_uri_from_config(mocker: MockerFixture) -> None:
"""
Test that get_oauth2_redirect_uri returns the configured value when set.
"""
custom_uri = "https://proxy.example.com/oauth2/"
mocker.patch(
"flask.current_app.config",
{"DATABASE_OAUTH2_REDIRECT_URI": custom_uri},
)
assert get_oauth2_redirect_uri() == custom_uri
def test_get_oauth2_redirect_uri_falls_back_to_url_for(mocker: MockerFixture) -> None:
"""
Test that get_oauth2_redirect_uri falls back to url_for when config is not set.
"""
fallback_uri = "http://localhost:8088/api/v1/database/oauth2/"
mocker.patch("flask.current_app.config", {})
mocker.patch(
"superset.utils.oauth2.url_for",
return_value=fallback_uri,
)
assert get_oauth2_redirect_uri() == fallback_uri
def test_get_oauth2_redirect_uri_raises_on_build_error(
mocker: MockerFixture,
) -> None:
"""
Test that get_oauth2_redirect_uri raises OAuth2Error when url_for raises
BuildError (e.g. in headless/MCP contexts).
"""
from werkzeug.routing import BuildError
from superset.exceptions import OAuth2Error
mocker.patch("flask.current_app.config", {})
mocker.patch(
"superset.utils.oauth2.url_for",
side_effect=BuildError("DatabaseRestApi.oauth2", {}, ("GET",)),
)
with pytest.raises(OAuth2Error):
get_oauth2_redirect_uri()
def test_get_oauth2_redirect_uri_raises_on_runtime_error(
mocker: MockerFixture,
) -> None:
"""
Test that get_oauth2_redirect_uri raises OAuth2Error when url_for raises
RuntimeError (e.g. no request context and no SERVER_NAME).
"""
from superset.exceptions import OAuth2Error
mocker.patch("flask.current_app.config", {})
mocker.patch(
"superset.utils.oauth2.url_for",
side_effect=RuntimeError("Unable to build URL outside of request context"),
)
with pytest.raises(OAuth2Error):
get_oauth2_redirect_uri()