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
