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

amitmiran pushed a commit to branch feat/dashboard_dataset_access
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 0cd982f72343b352163a383df7122c0f77cb9694
Author: amitmiran137 <[email protected]>
AuthorDate: Wed Apr 7 18:56:59 2021 +0300

    feat: provide data access based onb dashboard access
---
 superset/security/manager.py | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/superset/security/manager.py b/superset/security/manager.py
index 1c4419c..407d010 100644
--- a/superset/security/manager.py
+++ b/superset/security/manager.py
@@ -22,6 +22,7 @@ from typing import Any, Callable, cast, List, Optional, Set, 
Tuple, TYPE_CHECKIN
 
 from flask import current_app, g
 from flask_appbuilder import Model
+from flask_appbuilder.models.sqla.interface import SQLAInterface
 from flask_appbuilder.security.sqla.manager import SecurityManager
 from flask_appbuilder.security.sqla.models import (
     assoc_permissionview_role,
@@ -60,7 +61,7 @@ if TYPE_CHECKING:
     from superset.models.sql_lab import Query
     from superset.sql_parse import Table
     from superset.viz import BaseViz
-
+    from superset.models.slice import Slice
 
 logger = logging.getLogger(__name__)
 
@@ -995,7 +996,8 @@ class SupersetSecurityManager(  # pylint: 
disable=too-many-public-methods
             assert datasource
 
             if not (
-                self.can_access_schema(datasource)
+                self.can_access_based_on_dashboard(datasource)
+                or self.can_access_schema(datasource)
                 or self.can_access("datasource_access", datasource.perm or "")
             ):
                 raise SupersetSecurityException(
@@ -1125,3 +1127,24 @@ class SupersetSecurityManager(  # pylint: 
disable=too-many-public-methods
 
             if not can_access:
                 raise DashboardAccessDeniedError()
+
+    # pylint: disable=no-self-use
+    def can_access_based_on_dashboard(self, datasource: "BaseDatasource"):
+        from superset import db
+        from superset.dashboards.filters import DashboardFilter
+        from superset.connectors.sqla.models import SqlaTable
+        from superset.models.slice import Slice
+        from superset.models.dashboard import Dashboard
+
+        query = (
+            db.session.query(SqlaTable)
+            .join(Slice.table)
+            .filter(SqlaTable.id == datasource.id)
+        )
+
+        query = DashboardFilter("id", SQLAInterface(Dashboard, 
db.session)).apply(
+            query, None
+        )
+
+        exists = db.session.query(query.exists()).scalar()
+        return exists

Reply via email to