diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/ExtraOptions.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/ExtraOptions.tsx index 174ef6093..c046c2501 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/ExtraOptions.tsx +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/ExtraOptions.tsx @@ -292,12 +292,12 @@ const ExtraOptions = ({ checked={!!db?.impersonate_user} onChange={onInputChange} labelText={t( - 'Impersonate Logged In User (Presto, Hive, and GSheets)', + 'Impersonate Logged In User (Presto, Trino, Hive, and GSheets)', )} /> None: + """ + Update a configuration dictionary + that can set the correct properties for impersonating users + :param connect_args: config to be updated + :param uri: URI string + :param impersonate_user: Flag indicating if impersonation is enabled + :param username: Effective username + :return: None + """ + url = make_url(uri) + backend_name = url.get_backend_name() + + # Must be Trino connection, enable impersonation, and set optional param + # auth=LDAP|KERBEROS + # Set principal_username=$effective_username + if backend_name == "trino" and username is not None: + connect_args["user"] = username + + @classmethod + def modify_url_for_impersonation( + cls, url: URL, impersonate_user: bool, username: Optional[str] + ) -> None: + """ + Modify the SQL Alchemy URL object with the user to impersonate if applicable. + :param url: SQLAlchemy URL object + :param impersonate_user: Flag indicating if impersonation is enabled + :param username: Effective username + """ + # Do nothing and let update_impersonation_config take care of impersonation diff --git a/tests/model_tests.py b/tests/model_tests.py index da30d30a4..83b826ff8 100644 --- a/tests/model_tests.py +++ b/tests/model_tests.py @@ -157,6 +157,33 @@ class TestDatabaseModel(SupersetTestCase): "password": "original_user_password", } + @mock.patch("superset.models.core.create_engine") + def test_impersonate_user_trino(self, mocked_create_engine): + uri = "trino://localhost" + principal_user = "logged_in_user" + + model = Database(database_name="test_database", sqlalchemy_uri=uri) + + model.impersonate_user = True + model.get_sqla_engine(user_name=principal_user) + call_args = mocked_create_engine.call_args + + assert str(call_args[0][0]) == "trino://localhost" + + assert call_args[1]["connect_args"] == { + "user": "logged_in_user", + } + + uri = "trino://original_user:original_user_password@localhost" + model = Database(database_name="test_database", sqlalchemy_uri=uri) + model.impersonate_user = True + model.get_sqla_engine(user_name=principal_user) + call_args = mocked_create_engine.call_args + + assert str(call_args[0][0]) == "trino://original_user@localhost" + + assert call_args[1]["connect_args"] == {"user": "logged_in_user"} + @mock.patch("superset.models.core.create_engine") def test_impersonate_user_hive(self, mocked_create_engine): uri = "hive://localhost"