You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by va...@apache.org on 2026/08/26 03:41:43 UTC

(superset) 01/01: fix(trino): honor the verify arg for the user impersonation flow

This is an automated email from the ASF dual-hosted git repository.

Vitor-Avila pushed a commit to branch fix/trino-verify-oauth
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 52f7dfc7d3b0b87c31bbba703e883fb11bb51d19
Author: Vitor Avila <vi...@gmail.com>
AuthorDate: Wed Aug 26 00:41:07 2026 -0300

    fix(trino): honor the verify arg for the user impersonation flow
---
 superset/db_engine_specs/trino.py              |   3 +
 tests/unit_tests/db_engine_specs/test_trino.py | 106 +++++++++++++++++++++++++
 2 files changed, 109 insertions(+)

diff --git a/superset/db_engine_specs/trino.py b/superset/db_engine_specs/trino.py
index 78c18858b1d..d88405672eb 100644
--- a/superset/db_engine_specs/trino.py
+++ b/superset/db_engine_specs/trino.py
@@ -290,6 +290,9 @@ class TrinoEngineSpec(PrestoBaseEngineSpec):
             if user_token is not None:
                 http_session = requests.Session()
                 http_session.headers.update({"Authorization": f"Bearer {user_token}"})
+                # Persists `verify` to the new `http_session`
+                if "verify" in connect_args:
+                    http_session.verify = connect_args["verify"]
                 connect_args["http_session"] = http_session
 
         return url, engine_kwargs
diff --git a/tests/unit_tests/db_engine_specs/test_trino.py b/tests/unit_tests/db_engine_specs/test_trino.py
index b08118ea42d..1380c2ab2af 100644
--- a/tests/unit_tests/db_engine_specs/test_trino.py
+++ b/tests/unit_tests/db_engine_specs/test_trino.py
@@ -1753,3 +1753,109 @@ def test_unmask_encrypted_extra() -> None:
             "auth_params": {"username": "alice", "password": "old-password"},
         }
     )
+
+
+def test_impersonate_user_no_username() -> None:
+    """
+    Test impersonate_user when the connection string doesn't have a username value.
+
+    Without a username there is nothing to impersonate, so the URL and the
+    engine kwargs are returned untouched.
+    """
+    from superset.db_engine_specs.trino import TrinoEngineSpec
+
+    url = make_url("trino://host:443/catalog/schema")
+    engine_kwargs: dict[str, Any] = {}
+
+    new_url, new_kwargs = TrinoEngineSpec.impersonate_user(
+        database=MagicMock(),
+        username=None,
+        user_token="token",  # noqa: S106
+        url=url,
+        engine_kwargs=engine_kwargs,
+    )
+
+    assert new_url is url
+    assert new_kwargs == {}
+
+
+def test_impersonate_user_non_trino_backend() -> None:
+    """
+    Test impersonate_user for non-Trino backends.
+    """
+    from superset.db_engine_specs.trino import TrinoEngineSpec
+
+    url = make_url("presto://user@host:443/catalog/schema")
+    engine_kwargs: dict[str, Any] = {"connect_args": {}}
+
+    _, new_kwargs = TrinoEngineSpec.impersonate_user(
+        database=MagicMock(),
+        username="alice",
+        user_token=None,
+        url=url,
+        engine_kwargs=engine_kwargs,
+    )
+
+    assert new_kwargs["connect_args"] == {}
+
+
+def test_impersonate_user_without_token() -> None:
+    """
+    Test impersonate_user when there isn't a `user_token`.
+
+    Without a user token only the `user` connect arg is set; no HTTP session is
+    built, so the driver keeps handling `verify` itself.
+    """
+    from superset.db_engine_specs.trino import TrinoEngineSpec
+
+    url = make_url("trino://host:443/catalog/schema")
+    engine_kwargs: dict[str, Any] = {"connect_args": {"verify": False}}
+
+    _, new_kwargs = TrinoEngineSpec.impersonate_user(
+        database=MagicMock(),
+        username="alice",
+        user_token=None,
+        url=url,
+        engine_kwargs=engine_kwargs,
+    )
+
+    assert new_kwargs["connect_args"] == {"user": "alice", "verify": False}
+
+
+@pytest.mark.parametrize(
+    "verify",
+    [None, False, True, "/path/to/ca-bundle.pem"],
+)
+def test_impersonate_user_with_token(verify: Any) -> None:
+    """
+    Test impersonate_user with a `user_token`.
+
+    With a user token an HTTP session carrying the bearer token is injected.
+    """
+    from superset.db_engine_specs.trino import TrinoEngineSpec
+
+    url = make_url("trino://host:443/catalog/schema")
+    connect_args: dict[str, Any] = {}
+    if verify is not None:
+        connect_args["verify"] = verify
+    engine_kwargs: dict[str, Any] = {"connect_args": connect_args}
+
+    _, new_kwargs = TrinoEngineSpec.impersonate_user(
+        database=MagicMock(),
+        username="alice",
+        user_token="user-token",  # noqa: S106
+        url=url,
+        engine_kwargs=engine_kwargs,
+    )
+
+    connect_args = new_kwargs["connect_args"]
+    assert connect_args["user"] == "alice"
+    http_session = connect_args["http_session"]
+    assert http_session.headers["Authorization"] == "Bearer user-token"
+    if verify is not None:
+        assert connect_args["http_session"].verify == verify
+        # The original connect arg is left in place for the driver.
+        assert connect_args["verify"] == verify
+    # No `verify` was configured, so the session keeps the `requests` default.
+    else:
+        assert http_session.verify is True