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

beto pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new fb15278f97 fix: catalog permission check (#29581)
fb15278f97 is described below

commit fb15278f973d37e5fbed1a7674346b84b1fa5af8
Author: Beto Dealmeida <[email protected]>
AuthorDate: Fri Jul 12 21:00:13 2024 -0400

    fix: catalog permission check (#29581)
---
 superset/security/manager.py              |  9 ++++-
 tests/unit_tests/security/manager_test.py | 66 ++++++++++++++++++++++++++++++-
 2 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/superset/security/manager.py b/superset/security/manager.py
index 53fc9aa232..30cf37f117 100644
--- a/superset/security/manager.py
+++ b/superset/security/manager.py
@@ -860,7 +860,7 @@ class SupersetSecurityManager(  # pylint: 
disable=too-many-public-methods
             if len(parts) == 2 and default_catalog:
                 accessible_catalogs.add(default_catalog)
             elif len(parts) == 3:
-                accessible_catalogs.add(parts[2])
+                accessible_catalogs.add(parts[1])
 
         # datasource_access
         if perms := self.user_view_menu_names("datasource_access"):
@@ -911,7 +911,12 @@ class SupersetSecurityManager(  # pylint: 
disable=too-many-public-methods
                 return datasource_names
 
         if schema:
-            schema_perm = self.get_schema_perm(database, catalog, schema)
+            default_catalog = database.get_default_catalog()
+            schema_perm = self.get_schema_perm(
+                database.database_name,
+                catalog or default_catalog,
+                schema,
+            )
             if schema_perm and self.can_access("schema_access", schema_perm):
                 return datasource_names
 
diff --git a/tests/unit_tests/security/manager_test.py 
b/tests/unit_tests/security/manager_test.py
index a83e415529..924e2cbf28 100644
--- a/tests/unit_tests/security/manager_test.py
+++ b/tests/unit_tests/security/manager_test.py
@@ -32,7 +32,7 @@ from superset.security.manager import (
 )
 from superset.sql_parse import Table
 from superset.superset_typing import AdhocColumn, AdhocMetric
-from superset.utils.core import override_user
+from superset.utils.core import DatasourceName, override_user
 
 
 def test_security_manager(app_context: None) -> None:
@@ -760,3 +760,67 @@ def test_raise_for_access_catalog(
         == """You need access to the following tables: `db2.public.ab_user`,
             `all_database_access` or `all_datasource_access` permission"""
     )
+
+
+def test_get_datasources_accessible_by_user_schema_access(
+    mocker: MockerFixture,
+    app_context: None,
+) -> None:
+    """
+    Test that `get_datasources_accessible_by_user` works with schema 
permissions.
+    """
+    sm = SupersetSecurityManager(appbuilder)
+    mocker.patch.object(sm, "can_access_database", return_value=False)
+
+    database = mocker.MagicMock()
+    database.database_name = "db1"
+    database.get_default_catalog.return_value = "catalog2"
+
+    can_access = mocker.patch.object(sm, "can_access", return_value=True)
+
+    datasource_names = [
+        DatasourceName("table1", "schema1", "catalog2"),
+        DatasourceName("table2", "schema1", "catalog2"),
+    ]
+
+    assert sm.get_datasources_accessible_by_user(
+        database,
+        datasource_names,
+        catalog=None,
+        schema="schema1",
+    ) == [
+        DatasourceName("table1", "schema1", "catalog2"),
+        DatasourceName("table2", "schema1", "catalog2"),
+    ]
+
+    # Even though we passed `catalog=None,` the schema check uses the default 
catalog
+    # when building the schema permission, since the DB supports catalog.
+    can_access.assert_called_with("schema_access", 
"[db1].[catalog2].[schema1]")
+
+
+def test_get_catalogs_accessible_by_user_schema_access(
+    mocker: MockerFixture,
+    app_context: None,
+) -> None:
+    """
+    Test that `get_catalogs_accessible_by_user` works with schema permissions.
+    """
+    sm = SupersetSecurityManager(appbuilder)
+    mocker.patch.object(sm, "can_access_database", return_value=False)
+    mocker.patch.object(
+        sm,
+        "user_view_menu_names",
+        side_effect=[
+            set(),  # catalog_access
+            {"[db1].[catalog2].[schema1]"},  # schema_access
+            set(),  # datasource_access
+        ],
+    )
+
+    database = mocker.MagicMock()
+    database.database_name = "db1"
+    database.get_default_catalog.return_value = "catalog2"
+
+    catalogs = {"catalog1", "catalog2"}
+
+    assert sm.get_catalogs_accessible_by_user(database, catalogs) == 
{"catalog2"}

Reply via email to