refactor: Move raise_for_dashboard_access to security manager (#13235)
raise_for_dashboard_access is part of dashboard and cannot be overridden by a security manager.
This commit is contained in:
parent
6e3121268e
commit
99a0c8a8a1
|
|
@ -22,7 +22,6 @@ from functools import partial
|
|||
from typing import Any, Callable, Dict, List, Set, Union
|
||||
|
||||
import sqlalchemy as sqla
|
||||
from flask import g
|
||||
from flask_appbuilder import Model
|
||||
from flask_appbuilder.models.decorators import renders
|
||||
from flask_appbuilder.security.sqla.models import User
|
||||
|
|
@ -48,7 +47,6 @@ from superset import app, ConnectorRegistry, db, is_feature_enabled, security_ma
|
|||
from superset.connectors.base.models import BaseDatasource
|
||||
from superset.connectors.druid.models import DruidColumn, DruidMetric
|
||||
from superset.connectors.sqla.models import SqlMetric, TableColumn
|
||||
from superset.dashboards.commands.exceptions import DashboardAccessDeniedError
|
||||
from superset.extensions import cache_manager
|
||||
from superset.models.helpers import AuditMixinNullable, ImportExportMixin
|
||||
from superset.models.slice import Slice
|
||||
|
|
@ -422,22 +420,3 @@ if is_feature_enabled("DASHBOARD_CACHE"):
|
|||
sqla.event.listen(TableColumn, "after_update", clear_dashboard_cache)
|
||||
sqla.event.listen(DruidMetric, "after_update", clear_dashboard_cache)
|
||||
sqla.event.listen(DruidColumn, "after_update", clear_dashboard_cache)
|
||||
|
||||
|
||||
def raise_for_dashboard_access(dashboard: Dashboard) -> None:
|
||||
from superset.views.base import get_user_roles, is_user_admin
|
||||
from superset.views.utils import is_owner
|
||||
|
||||
if is_feature_enabled("DASHBOARD_RBAC"):
|
||||
has_rbac_access = any(
|
||||
dashboard_role.id in [user_role.id for user_role in get_user_roles()]
|
||||
for dashboard_role in dashboard.roles
|
||||
)
|
||||
can_access = (
|
||||
is_user_admin()
|
||||
or is_owner(dashboard, g.user)
|
||||
or (dashboard.published and has_rbac_access)
|
||||
)
|
||||
|
||||
if not can_access:
|
||||
raise DashboardAccessDeniedError()
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ if TYPE_CHECKING:
|
|||
from superset.common.query_context import QueryContext
|
||||
from superset.connectors.base.models import BaseDatasource
|
||||
from superset.connectors.druid.models import DruidCluster
|
||||
from superset.models.dashboard import Dashboard
|
||||
from superset.models.core import Database
|
||||
from superset.models.sql_lab import Query
|
||||
from superset.sql_parse import Table
|
||||
|
|
@ -1097,3 +1098,30 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
|
|||
ids = [f.id for f in self.get_rls_filters(table)]
|
||||
ids.sort() # Combinations rather than permutations
|
||||
return ids
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
def raise_for_dashboard_access(self, dashboard: "Dashboard") -> None:
|
||||
"""
|
||||
Raise an exception if the user cannot access the dashboard.
|
||||
|
||||
:param dashboard: Dashboard the user wants access to
|
||||
:raises DashboardAccessDeniedError: If the user cannot access the resource
|
||||
"""
|
||||
from superset.dashboards.commands.exceptions import DashboardAccessDeniedError
|
||||
from superset.views.base import get_user_roles, is_user_admin
|
||||
from superset.views.utils import is_owner
|
||||
from superset import is_feature_enabled
|
||||
|
||||
if is_feature_enabled("DASHBOARD_RBAC"):
|
||||
has_rbac_access = any(
|
||||
dashboard_role.id in [user_role.id for user_role in get_user_roles()]
|
||||
for dashboard_role in dashboard.roles
|
||||
)
|
||||
can_access = (
|
||||
is_user_admin()
|
||||
or is_owner(dashboard, g.user)
|
||||
or (dashboard.published and has_rbac_access)
|
||||
)
|
||||
|
||||
if not can_access:
|
||||
raise DashboardAccessDeniedError()
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ from functools import wraps
|
|||
from typing import Any, Callable, Dict, Iterator, Union
|
||||
|
||||
from contextlib2 import contextmanager
|
||||
from flask import Response
|
||||
from flask import current_app, Response
|
||||
|
||||
from superset import is_feature_enabled
|
||||
from superset.dashboards.commands.exceptions import DashboardAccessDeniedError
|
||||
|
|
@ -87,15 +87,12 @@ def check_dashboard_access(
|
|||
def decorator(f: Callable[..., Any]) -> Callable[..., Any]:
|
||||
@wraps(f)
|
||||
def wrapper(self: Any, *args: Any, **kwargs: Any) -> Any:
|
||||
from superset.models.dashboard import (
|
||||
Dashboard,
|
||||
raise_for_dashboard_access,
|
||||
)
|
||||
from superset.models.dashboard import Dashboard
|
||||
|
||||
dashboard = Dashboard.get(str(kwargs["dashboard_id_or_slug"]))
|
||||
if is_feature_enabled("DASHBOARD_RBAC"):
|
||||
try:
|
||||
raise_for_dashboard_access(dashboard)
|
||||
current_app.appbuilder.sm.raise_for_dashboard_access(dashboard)
|
||||
except DashboardAccessDeniedError as ex:
|
||||
return on_error(self, ex)
|
||||
except Exception as exception:
|
||||
|
|
|
|||
Loading…
Reference in New Issue