diff --git a/superset/commands/database/utils.py b/superset/commands/database/utils.py index 2c113173fbfd..186bccc8a24a 100644 --- a/superset/commands/database/utils.py +++ b/superset/commands/database/utils.py @@ -57,10 +57,21 @@ def add_permissions(database: Database, ssh_tunnel: SSHTunnel | None) -> None: """ # TODO: Migrate this to use the non-commiting add_pvm helper instead if database.db_engine_spec.supports_catalog: - catalogs = database.get_all_catalog_names( - cache=False, - ssh_tunnel=ssh_tunnel, - ) + # Adding permissions to all catalogs (and all their schemas) can take a long + # time (minutes, while importing a chart, eg). If the database does not + # support cross-catalog queries (like Postgres), and the multi-catalog + # feature is not enabled, then we only need to add permissions to the + # default catalog. + if ( + database.db_engine_spec.supports_cross_catalog_queries + or database.allow_multi_catalog + ): + catalogs = database.get_all_catalog_names( + cache=False, + ssh_tunnel=ssh_tunnel, + ) + else: + catalogs = {database.get_default_catalog()} for catalog in catalogs: security_manager.add_permission_view_menu( diff --git a/tests/unit_tests/databases/commands/utils_test.py b/tests/unit_tests/databases/commands/utils_test.py index e8f27d041602..0e5393639fd1 100644 --- a/tests/unit_tests/databases/commands/utils_test.py +++ b/tests/unit_tests/databases/commands/utils_test.py @@ -47,6 +47,37 @@ def test_add_permissions(mocker: MockerFixture) -> None: ) +def test_add_permissions_get_default_catalog(mocker: MockerFixture): + """ + Test permissions only added to the default catalog if multi-catalog is not enabled. + Important when the database does not support cross-catalog queries (like Postgres). + """ + database = mocker.MagicMock() + database.database_name = "my_db" + database.db_engine_spec.supports_catalog = True + database.db_engine_spec.supports_cross_catalog_queries = False + database.allow_multi_catalog = False + database.get_all_catalog_names.return_value = ["catalog1", "catalog2"] + database.get_default_catalog.return_value = "catalog1" + database.get_all_schema_names.side_effect = [["schema1"], ["schema2"]] + ssh_tunnel = mocker.MagicMock() + add_permission_view_menu = mocker.patch( + "superset.commands.database.importers.v1.utils.security_manager." + "add_permission_view_menu" + ) + + add_permissions(database, ssh_tunnel) + + add_permission_view_menu.assert_has_calls( + [ + mocker.call("catalog_access", "[my_db].[catalog1]"), + mocker.call("schema_access", "[my_db].[catalog1].[schema1]"), + ] + ) + + assert add_permission_view_menu.call_count == 2 + + def test_add_permissions_handle_failures(mocker: MockerFixture) -> None: """ Test adding permissions to a database when it's created in case