fix: chart import validation (#26993)

This commit is contained in:
Daniel Vaz Gaspar
2024-02-06 12:14:02 +00:00
committed by Michael S. Molina
parent e772915bb8
commit c029475f60
13 changed files with 404 additions and 146 deletions

View File

@@ -82,6 +82,7 @@ if TYPE_CHECKING:
from superset.connectors.sqla.models import RowLevelSecurityFilter, SqlaTable
from superset.models.core import Database
from superset.models.dashboard import Dashboard
from superset.models.slice import Slice
from superset.models.sql_lab import Query
from superset.sql_parse import Table
from superset.viz import BaseViz
@@ -420,6 +421,19 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
return True
def can_access_chart(self, chart: "Slice") -> bool:
"""
Return True if the user can access the specified chart, False otherwise.
:param chart: The chart
:return: Whether the user can access the chart
"""
try:
self.raise_for_access(chart=chart)
except SupersetSecurityException:
return False
return True
# pylint: disable=no-self-use
def get_dashboard_access_error_object( # pylint: disable=invalid-name
self,
@@ -438,6 +452,23 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
level=ErrorLevel.ERROR,
)
def get_chart_access_error_object(
self,
dashboard: "Dashboard", # pylint: disable=unused-argument
) -> SupersetError:
"""
Return the error object for the denied Superset dashboard.
:param dashboard: The denied Superset dashboard
:returns: The error object
"""
return SupersetError(
error_type=SupersetErrorType.CHART_SECURITY_ACCESS_ERROR,
message="You don't have access to this chart.",
level=ErrorLevel.ERROR,
)
@staticmethod
def get_datasource_access_error_msg(datasource: "BaseDatasource") -> str:
"""
@@ -1800,6 +1831,7 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
# pylint: disable=too-many-arguments,too-many-branches,too-many-locals,too-many-statements
self,
dashboard: Optional["Dashboard"] = None,
chart: Optional["Slice"] = None,
database: Optional["Database"] = None,
datasource: Optional["BaseDatasource"] = None,
query: Optional["Query"] = None,
@@ -2025,6 +2057,15 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
self.get_dashboard_access_error_object(dashboard)
)
if chart:
if self.is_admin() or self.is_owner(chart):
return
if chart.datasource and self.can_access_datasource(chart.datasource):
return
raise SupersetSecurityException(self.get_chart_access_error_object(chart))
def get_user_by_username(
self, username: str, session: Session = None
) -> Optional[User]: