def _get_notification_content(self) -> NotificationContent: """ Gets a notification content, this is composed by a title and a screenshot :raises: ReportScheduleScreenshotFailedError """ screenshot_data = None url = self._get_url(user_friendly=True) if (feature_flag_manager.is_feature_enabled("ALERTS_ATTACH_REPORTS") or self._report_schedule.type == ReportScheduleType.REPORT): screenshot_data = self._get_screenshot() if not screenshot_data: return NotificationContent( name=self._report_schedule.name, text="Unexpected missing screenshot", ) if self._report_schedule.chart: name = (f"{self._report_schedule.name}: " f"{self._report_schedule.chart.slice_name}") else: name = (f"{self._report_schedule.name}: " f"{self._report_schedule.dashboard.dashboard_title}") return NotificationContent(name=name, url=url, screenshot=screenshot_data)
def request_loader(self, request: Request) -> Optional[User]: # pylint: disable=import-outside-toplevel from superset.extensions import feature_flag_manager if feature_flag_manager.is_feature_enabled("EMBEDDED_SUPERSET"): return self.get_guest_user_from_request(request) return None
def create_login_manager(self, app: Flask) -> LoginManager: # pylint: disable=import-outside-toplevel from superset.extensions import feature_flag_manager lm = super().create_login_manager(app) if feature_flag_manager.is_feature_enabled("EMBEDDED_SUPERSET"): lm.request_loader(self.get_guest_user_from_request) return lm
def _get_notification_content(self) -> NotificationContent: """ Gets a notification content, this is composed by a title and a screenshot :raises: ReportScheduleScreenshotFailedError """ csv_data = None embedded_data = None error_text = None screenshot_data = [] url = self._get_url(user_friendly=True) if ( feature_flag_manager.is_feature_enabled("ALERTS_ATTACH_REPORTS") or self._report_schedule.type == ReportScheduleType.REPORT ): if self._report_schedule.report_format == ReportDataFormat.VISUALIZATION: screenshot_data = self._get_screenshots() if not screenshot_data: error_text = "Unexpected missing screenshot" elif ( self._report_schedule.chart and self._report_schedule.report_format == ReportDataFormat.DATA ): csv_data = self._get_csv_data() if not csv_data: error_text = "Unexpected missing csv file" if error_text: return NotificationContent( name=self._report_schedule.name, text=error_text ) if ( self._report_schedule.chart and self._report_schedule.report_format == ReportDataFormat.TEXT ): embedded_data = self._get_embedded_data() if self._report_schedule.chart: name = ( f"{self._report_schedule.name}: " f"{self._report_schedule.chart.slice_name}" ) else: name = ( f"{self._report_schedule.name}: " f"{self._report_schedule.dashboard.dashboard_title}" ) return NotificationContent( name=name, url=url, screenshots=screenshot_data, description=self._report_schedule.description, csv=csv_data, embedded_data=embedded_data, )
def get_template_processor( database: "Database", table: Optional["SqlaTable"] = None, query: Optional["Query"] = None, **kwargs: Any, ) -> BaseTemplateProcessor: if feature_flag_manager.is_feature_enabled("ENABLE_TEMPLATE_PROCESSING"): template_processor = get_template_processors().get( database.backend, JinjaTemplateProcessor ) else: template_processor = NoOpTemplateProcessor return template_processor(database=database, table=table, query=query, **kwargs)
def raise_for_access( # pylint: disable=too-many-arguments,too-many-locals self, database: Optional["Database"] = None, datasource: Optional["BaseDatasource"] = None, query: Optional["Query"] = None, query_context: Optional["QueryContext"] = None, table: Optional["Table"] = None, viz: Optional["BaseViz"] = None, ) -> None: """ Raise an exception if the user cannot access the resource. :param database: The Superset database :param datasource: The Superset datasource :param query: The SQL Lab query :param query_context: The query context :param table: The Superset table (requires database) :param viz: The visualization :raises SupersetSecurityException: If the user cannot access the resource """ # pylint: disable=import-outside-toplevel from superset.connectors.sqla.models import SqlaTable from superset.extensions import feature_flag_manager from superset.sql_parse import Table if database and table or query: if query: database = query.database database = cast("Database", database) if self.can_access_database(database): return if query: tables = { Table(table_.table, table_.schema or query.schema) for table_ in sql_parse.ParsedQuery(query.sql).tables } elif table: tables = {table} denied = set() for table_ in tables: schema_perm = self.get_schema_perm(database, schema=table_.schema) if not (schema_perm and self.can_access("schema_access", schema_perm)): datasources = SqlaTable.query_datasources_by_name( self.get_session, database, table_.table, schema=table_.schema) # Access to any datasource is suffice. for datasource_ in datasources: if self.can_access("datasource_access", datasource_.perm): break else: denied.add(table_) if denied: raise SupersetSecurityException( self.get_table_access_error_object(denied)) if datasource or query_context or viz: if query_context: datasource = query_context.datasource elif viz: datasource = viz.datasource assert datasource should_check_dashboard_access = ( feature_flag_manager.is_feature_enabled("DASHBOARD_RBAC") or self.is_guest_user()) if not (self.can_access_schema(datasource) or self.can_access( "datasource_access", datasource.perm or "") or (should_check_dashboard_access and self.can_access_based_on_dashboard(datasource))): raise SupersetSecurityException( self.get_datasource_access_error_object(datasource))
def configure_async_queries(self) -> None: if feature_flag_manager.is_feature_enabled("GLOBAL_ASYNC_QUERIES"): async_query_manager.init_app(self.superset_app)
def init_views(self) -> None: # # We're doing local imports, as several of them import # models which in turn try to import # the global Flask app # # pylint: disable=import-outside-toplevel,too-many-locals,too-many-statements from superset.advanced_data_type.api import AdvancedDataTypeRestApi from superset.annotation_layers.annotations.api import AnnotationRestApi from superset.annotation_layers.api import AnnotationLayerRestApi from superset.async_events.api import AsyncEventsRestApi from superset.cachekeys.api import CacheRestApi from superset.charts.api import ChartRestApi from superset.charts.data.api import ChartDataRestApi from superset.connectors.sqla.views import ( RowLevelSecurityFiltersModelView, SqlMetricInlineView, TableColumnInlineView, TableModelView, ) from superset.css_templates.api import CssTemplateRestApi from superset.dashboards.api import DashboardRestApi from superset.dashboards.filter_sets.api import FilterSetRestApi from superset.dashboards.filter_state.api import DashboardFilterStateRestApi from superset.dashboards.permalink.api import DashboardPermalinkRestApi from superset.databases.api import DatabaseRestApi from superset.datasets.api import DatasetRestApi from superset.datasets.columns.api import DatasetColumnsRestApi from superset.datasets.metrics.api import DatasetMetricRestApi from superset.embedded.api import EmbeddedDashboardRestApi from superset.embedded.view import EmbeddedView from superset.explore.api import ExploreRestApi from superset.explore.form_data.api import ExploreFormDataRestApi from superset.explore.permalink.api import ExplorePermalinkRestApi from superset.importexport.api import ImportExportRestApi from superset.queries.api import QueryRestApi from superset.queries.saved_queries.api import SavedQueryRestApi from superset.reports.api import ReportScheduleRestApi from superset.reports.logs.api import ReportExecutionLogRestApi from superset.security.api import SecurityRestApi from superset.views.access_requests import AccessRequestsModelView from superset.views.alerts import AlertView, ReportView from superset.views.annotations import ( AnnotationLayerModelView, AnnotationModelView, ) from superset.views.api import Api from superset.views.chart.views import SliceAsync, SliceModelView from superset.views.core import Superset from superset.views.css_templates import ( CssTemplateAsyncModelView, CssTemplateModelView, ) from superset.views.dashboard.views import ( Dashboard, DashboardModelView, DashboardModelViewAsync, ) from superset.views.database.views import ( ColumnarToDatabaseView, CsvToDatabaseView, DatabaseView, ExcelToDatabaseView, ) from superset.views.datasource.views import DatasetEditor, Datasource from superset.views.dynamic_plugins import DynamicPluginsView from superset.views.explore import ExplorePermalinkView, ExploreView from superset.views.key_value import KV from superset.views.log.api import LogRestApi from superset.views.log.views import LogModelView from superset.views.redirects import R from superset.views.sql_lab.views import ( SavedQueryView, SavedQueryViewApi, SqlLab, TableSchemaView, TabStateView, ) from superset.views.tags import TagView from superset.views.users.api import CurrentUserRestApi # # Setup API views # appbuilder.add_api(AnnotationRestApi) appbuilder.add_api(AnnotationLayerRestApi) appbuilder.add_api(AsyncEventsRestApi) appbuilder.add_api(AdvancedDataTypeRestApi) appbuilder.add_api(CacheRestApi) appbuilder.add_api(ChartRestApi) appbuilder.add_api(ChartDataRestApi) appbuilder.add_api(CssTemplateRestApi) appbuilder.add_api(CurrentUserRestApi) appbuilder.add_api(DashboardFilterStateRestApi) appbuilder.add_api(DashboardPermalinkRestApi) appbuilder.add_api(DashboardRestApi) appbuilder.add_api(DatabaseRestApi) appbuilder.add_api(DatasetRestApi) appbuilder.add_api(DatasetColumnsRestApi) appbuilder.add_api(DatasetMetricRestApi) appbuilder.add_api(EmbeddedDashboardRestApi) appbuilder.add_api(ExploreRestApi) appbuilder.add_api(ExploreFormDataRestApi) appbuilder.add_api(ExplorePermalinkRestApi) appbuilder.add_api(FilterSetRestApi) appbuilder.add_api(ImportExportRestApi) appbuilder.add_api(QueryRestApi) appbuilder.add_api(ReportScheduleRestApi) appbuilder.add_api(ReportExecutionLogRestApi) appbuilder.add_api(SavedQueryRestApi) # # Setup regular views # appbuilder.add_link( "Home", label=__("Home"), href="/superset/welcome/", cond=lambda: bool(appbuilder.app.config["LOGO_TARGET_PATH"]), ) appbuilder.add_view( AnnotationLayerModelView, "Annotation Layers", label=__("Annotation Layers"), icon="fa-comment", category="Manage", category_label=__("Manage"), category_icon="", ) appbuilder.add_view( DashboardModelView, "Dashboards", label=__("Dashboards"), icon="fa-dashboard", category="", category_icon="", ) appbuilder.add_view( SliceModelView, "Charts", label=__("Charts"), icon="fa-bar-chart", category="", category_icon="", ) appbuilder.add_view( DynamicPluginsView, "Plugins", label=__("Plugins"), category="Manage", category_label=__("Manage"), icon="fa-puzzle-piece", menu_cond=lambda: feature_flag_manager.is_feature_enabled( "DYNAMIC_PLUGINS"), ) appbuilder.add_view( CssTemplateModelView, "CSS Templates", label=__("CSS Templates"), icon="fa-css3", category="Manage", category_label=__("Manage"), category_icon="", ) appbuilder.add_view( RowLevelSecurityFiltersModelView, "Row Level Security", label=__("Row Level Security"), category="Security", category_label=__("Security"), icon="fa-lock", ) # # Setup views with no menu # appbuilder.add_view_no_menu(Api) appbuilder.add_view_no_menu(CssTemplateAsyncModelView) appbuilder.add_view_no_menu(CsvToDatabaseView) appbuilder.add_view_no_menu(ExcelToDatabaseView) appbuilder.add_view_no_menu(ColumnarToDatabaseView) appbuilder.add_view_no_menu(Dashboard) appbuilder.add_view_no_menu(DashboardModelViewAsync) appbuilder.add_view_no_menu(Datasource) appbuilder.add_view_no_menu(DatasetEditor) appbuilder.add_view_no_menu(EmbeddedView) appbuilder.add_view_no_menu(ExploreView) appbuilder.add_view_no_menu(ExplorePermalinkView) appbuilder.add_view_no_menu(KV) appbuilder.add_view_no_menu(R) appbuilder.add_view_no_menu(SavedQueryView) appbuilder.add_view_no_menu(SavedQueryViewApi) appbuilder.add_view_no_menu(SliceAsync) appbuilder.add_view_no_menu(SqlLab) appbuilder.add_view_no_menu(SqlMetricInlineView) appbuilder.add_view_no_menu(AnnotationModelView) appbuilder.add_view_no_menu(Superset) appbuilder.add_view_no_menu(TableColumnInlineView) appbuilder.add_view_no_menu(TableModelView) appbuilder.add_view_no_menu(TableSchemaView) appbuilder.add_view_no_menu(TabStateView) appbuilder.add_view_no_menu(TagView) appbuilder.add_view_no_menu(ReportView) # # Add links # appbuilder.add_link( "Import Dashboards", label=__("Import Dashboards"), href="/superset/import_dashboards/", icon="fa-cloud-upload", category="Manage", category_label=__("Manage"), category_icon="fa-wrench", cond=lambda: not feature_flag_manager.is_feature_enabled( "VERSIONED_EXPORT"), ) appbuilder.add_link( "SQL Editor", label=_("SQL Editor"), href="/superset/sqllab/", category_icon="fa-flask", icon="fa-flask", category="SQL Lab", category_label=__("SQL Lab"), ) appbuilder.add_link( __("Saved Queries"), href="/savedqueryview/list/", icon="fa-save", category="SQL Lab", ) appbuilder.add_link( "Query Search", label=_("Query History"), href="/superset/sqllab/history/", icon="fa-search", category_icon="fa-flask", category="SQL Lab", category_label=__("SQL Lab"), ) appbuilder.add_view( DatabaseView, "Databases", label=__("Databases"), icon="fa-database", category="Data", category_label=__("Data"), category_icon="fa-database", ) appbuilder.add_link( "Datasets", label=__("Datasets"), href="/tablemodelview/list/", icon="fa-table", category="Data", category_label=__("Data"), category_icon="fa-table", ) appbuilder.add_separator("Data") appbuilder.add_api(LogRestApi) appbuilder.add_view( LogModelView, "Action Log", label=__("Action Log"), category="Security", category_label=__("Security"), icon="fa-list-ol", menu_cond=lambda: (self.config["FAB_ADD_SECURITY_VIEWS"] and self. config["SUPERSET_LOG_VIEW"]), ) appbuilder.add_api(SecurityRestApi) # # Conditionally setup email views # appbuilder.add_view( AlertView, "Alerts & Report", label=__("Alerts & Reports"), category="Manage", category_label=__("Manage"), icon="fa-exclamation-triangle", menu_cond=lambda: feature_flag_manager.is_feature_enabled( "ALERT_REPORTS"), ) appbuilder.add_view( AccessRequestsModelView, "Access requests", label=__("Access requests"), category="Security", category_label=__("Security"), icon="fa-table", menu_cond=lambda: bool(self.config["ENABLE_ACCESS_REQUEST"]), )
def init_views(self) -> None: # # We're doing local imports, as several of them import # models which in turn try to import # the global Flask app # # pylint: disable=too-many-locals # pylint: disable=too-many-statements from superset.cachekeys.api import CacheRestApi from superset.charts.api import ChartRestApi from superset.connectors.druid.views import ( Druid, DruidClusterModelView, DruidColumnInlineView, DruidDatasourceModelView, DruidMetricInlineView, ) from superset.connectors.sqla.views import ( RowLevelSecurityFiltersModelView, SqlMetricInlineView, TableColumnInlineView, TableModelView, ) from superset.css_templates.api import CssTemplateRestApi from superset.dashboards.api import DashboardRestApi from superset.databases.api import DatabaseRestApi from superset.datasets.api import DatasetRestApi from superset.queries.api import QueryRestApi from superset.queries.saved_queries.api import SavedQueryRestApi from superset.views.access_requests import AccessRequestsModelView from superset.views.alerts import ( AlertLogModelView, AlertModelView, AlertObservationModelView, ) from superset.views.annotations import ( AnnotationLayerModelView, AnnotationModelView, ) from superset.views.api import Api from superset.views.chart.views import SliceAsync, SliceModelView from superset.views.core import Superset from superset.views.css_templates import ( CssTemplateAsyncModelView, CssTemplateModelView, ) from superset.views.dashboard.views import ( Dashboard, DashboardModelView, DashboardModelViewAsync, ) from superset.views.database.views import ( CsvToDatabaseView, DatabaseView, ExcelToDatabaseView, ) from superset.views.datasource import Datasource from superset.views.key_value import KV from superset.views.log.api import LogRestApi from superset.views.log.views import LogModelView from superset.views.redirects import R from superset.views.schedules import ( DashboardEmailScheduleView, SliceEmailScheduleView, ) from superset.views.sql_lab import ( SavedQueryView, SavedQueryViewApi, SqlLab, TableSchemaView, TabStateView, ) from superset.views.tags import TagView # # Setup API views # appbuilder.add_api(CacheRestApi) appbuilder.add_api(ChartRestApi) appbuilder.add_api(CssTemplateRestApi) appbuilder.add_api(DashboardRestApi) appbuilder.add_api(DatabaseRestApi) appbuilder.add_api(DatasetRestApi) appbuilder.add_api(QueryRestApi) appbuilder.add_api(SavedQueryRestApi) # # Setup regular views # appbuilder.add_view( AnnotationLayerModelView, "Annotation Layers", label=__("Annotation Layers"), icon="fa-comment", category="Manage", category_label=__("Manage"), category_icon="", ) appbuilder.add_view( DatabaseView, "Databases", label=__("Databases"), icon="fa-database", category="Data", category_label=__("Data"), category_icon="fa-database", ) appbuilder.add_link( "Datasets", label=__("Datasets"), href="/tablemodelview/list/?_flt_1_is_sqllab_view=y", icon="fa-table", category="Data", category_label=__("Data"), category_icon="fa-table", ) appbuilder.add_separator("Data") appbuilder.add_view( SliceModelView, "Charts", label=__("Charts"), icon="fa-bar-chart", category="", category_icon="", ) appbuilder.add_view( DashboardModelView, "Dashboards", label=__("Dashboards"), icon="fa-dashboard", category="", category_icon="", ) appbuilder.add_view( CssTemplateModelView, "CSS Templates", label=__("CSS Templates"), icon="fa-css3", category="Manage", category_label=__("Manage"), category_icon="", ) if self.config["ENABLE_ROW_LEVEL_SECURITY"]: appbuilder.add_view( RowLevelSecurityFiltersModelView, "Row Level Security", label=__("Row level security"), category="Security", category_label=__("Security"), icon="fa-lock", ) # # Setup views with no menu # appbuilder.add_view_no_menu(Api) appbuilder.add_view_no_menu(CssTemplateAsyncModelView) appbuilder.add_view_no_menu(CsvToDatabaseView) appbuilder.add_view_no_menu(ExcelToDatabaseView) appbuilder.add_view_no_menu(Dashboard) appbuilder.add_view_no_menu(DashboardModelViewAsync) appbuilder.add_view_no_menu(Datasource) if feature_flag_manager.is_feature_enabled("KV_STORE"): appbuilder.add_view_no_menu(KV) appbuilder.add_view_no_menu(R) appbuilder.add_view_no_menu(SavedQueryView) appbuilder.add_view_no_menu(SavedQueryViewApi) appbuilder.add_view_no_menu(SliceAsync) appbuilder.add_view_no_menu(SqlLab) appbuilder.add_view_no_menu(SqlMetricInlineView) appbuilder.add_view_no_menu(AnnotationModelView) appbuilder.add_view_no_menu(Superset) appbuilder.add_view_no_menu(TableColumnInlineView) appbuilder.add_view_no_menu(TableModelView) appbuilder.add_view_no_menu(TableSchemaView) appbuilder.add_view_no_menu(TabStateView) if feature_flag_manager.is_feature_enabled("TAGGING_SYSTEM"): appbuilder.add_view_no_menu(TagView) # # Add links # appbuilder.add_link( "Import Dashboards", label=__("Import Dashboards"), href="/superset/import_dashboards", icon="fa-cloud-upload", category="Manage", category_label=__("Manage"), category_icon="fa-wrench", ) appbuilder.add_link( "SQL Editor", label=_("SQL Editor"), href="/superset/sqllab", category_icon="fa-flask", icon="fa-flask", category="SQL Lab", category_label=__("SQL Lab"), ) appbuilder.add_link( __("Saved Queries"), href="/sqllab/my_queries/", icon="fa-save", category="SQL Lab", ) appbuilder.add_link( "Query Search", label=_("Query Search"), href="/superset/sqllab#search", icon="fa-search", category_icon="fa-flask", category="SQL Lab", category_label=__("SQL Lab"), ) if self.config["CSV_EXTENSIONS"].intersection( self.config["ALLOWED_EXTENSIONS"]): appbuilder.add_link( "Upload a CSV", label=__("Upload a CSV"), href="/csvtodatabaseview/form", icon="fa-upload", category="Data", category_label=__("Data"), category_icon="fa-wrench", ) try: import xlrd # pylint: disable=unused-import if self.config["EXCEL_EXTENSIONS"].intersection( self.config["ALLOWED_EXTENSIONS"]): appbuilder.add_link( "Upload Excel", label=__("Upload Excel"), href="/exceltodatabaseview/form", icon="fa-upload", category="Data", category_label=__("Data"), category_icon="fa-wrench", ) except ImportError: pass # # Conditionally setup log views # if self.config["FAB_ADD_SECURITY_VIEWS"] and self.config[ "SUPERSET_LOG_VIEW"]: appbuilder.add_api(LogRestApi) appbuilder.add_view( LogModelView, "Action Log", label=__("Action Log"), category="Security", category_label=__("Security"), icon="fa-list-ol", ) # # Conditionally setup email views # if self.config["ENABLE_SCHEDULED_EMAIL_REPORTS"]: appbuilder.add_separator("Manage") appbuilder.add_view( DashboardEmailScheduleView, "Dashboard Email Schedules", label=__("Dashboard Emails"), category="Manage", category_label=__("Manage"), icon="fa-search", ) appbuilder.add_view( SliceEmailScheduleView, "Chart Emails", label=__("Chart Email Schedules"), category="Manage", category_label=__("Manage"), icon="fa-search", ) if self.config["ENABLE_ALERTS"]: appbuilder.add_view( AlertModelView, "Alerts", label=__("Alerts"), category="Manage", category_label=__("Manage"), icon="fa-exclamation-triangle", ) appbuilder.add_view_no_menu(AlertObservationModelView) appbuilder.add_view_no_menu(AlertLogModelView) # # Conditionally add Access Request Model View # if self.config["ENABLE_ACCESS_REQUEST"]: appbuilder.add_view( AccessRequestsModelView, "Access requests", label=__("Access requests"), category="Security", category_label=__("Security"), icon="fa-table", ) # # Conditionally setup Druid Views # if self.config["DRUID_IS_ACTIVE"]: appbuilder.add_separator("Data") appbuilder.add_view( DruidDatasourceModelView, "Druid Datasources", label=__("Druid Datasources"), category="Data", category_label=__("Data"), icon="fa-cube", ) appbuilder.add_view( DruidClusterModelView, name="Druid Clusters", label=__("Druid Clusters"), icon="fa-cubes", category="Data", category_label=__("Data"), category_icon="fa-database", ) appbuilder.add_view_no_menu(DruidMetricInlineView) appbuilder.add_view_no_menu(DruidColumnInlineView) appbuilder.add_view_no_menu(Druid) if self.config["DRUID_METADATA_LINKS_ENABLED"]: appbuilder.add_link( "Scan New Datasources", label=__("Scan New Datasources"), href="/druid/scan_new_datasources/", category="Data", category_label=__("Data"), category_icon="fa-database", icon="fa-refresh", ) appbuilder.add_link( "Refresh Druid Metadata", label=__("Refresh Druid Metadata"), href="/druid/refresh_datasources/", category="Data", category_label=__("Data"), category_icon="fa-database", icon="fa-cog", ) appbuilder.add_separator("Data")
def init_views(self) -> None: # # We're doing local imports, as several of them import # models which in turn try to import # the global Flask app # # pylint: disable=too-many-locals # pylint: disable=too-many-statements # pylint: disable=too-many-branches from superset.annotation_layers.api import AnnotationLayerRestApi from superset.annotation_layers.annotations.api import AnnotationRestApi from superset.async_events.api import AsyncEventsRestApi from superset.cachekeys.api import CacheRestApi from superset.charts.api import ChartRestApi from superset.connectors.druid.views import ( Druid, DruidClusterModelView, DruidColumnInlineView, DruidDatasourceModelView, DruidMetricInlineView, ) from superset.connectors.sqla.views import ( RowLevelSecurityFiltersModelView, SqlMetricInlineView, TableColumnInlineView, TableModelView, ) from superset.css_templates.api import CssTemplateRestApi from superset.dashboards.api import DashboardRestApi from superset.databases.api import DatabaseRestApi from superset.datasets.api import DatasetRestApi from superset.datasets.columns.api import DatasetColumnsRestApi from superset.datasets.metrics.api import DatasetMetricRestApi from superset.queries.api import QueryRestApi from superset.security.api import SecurityRestApi from superset.queries.saved_queries.api import SavedQueryRestApi from superset.reports.api import ReportScheduleRestApi from superset.reports.logs.api import ReportExecutionLogRestApi from superset.views.access_requests import AccessRequestsModelView from superset.views.alerts import ( AlertLogModelView, AlertModelView, AlertObservationModelView, AlertView, ReportView, ) from superset.views.annotations import ( AnnotationLayerModelView, AnnotationModelView, ) from superset.views.api import Api from superset.views.chart.views import SliceAsync, SliceModelView from superset.views.core import Superset from superset.views.css_templates import ( CssTemplateAsyncModelView, CssTemplateModelView, ) from superset.views.dashboard.views import ( Dashboard, DashboardModelView, DashboardModelViewAsync, ) from superset.views.database.views import ( CsvToDatabaseView, DatabaseView, ExcelToDatabaseView, ) from superset.views.datasource import Datasource from superset.views.dynamic_plugins import DynamicPluginsView from superset.views.key_value import KV from superset.views.log.api import LogRestApi from superset.views.log.views import LogModelView from superset.views.redirects import R from superset.views.schedules import ( DashboardEmailScheduleView, SliceEmailScheduleView, ) from superset.views.sql_lab import ( SavedQueryView, SavedQueryViewApi, SqlLab, TableSchemaView, TabStateView, ) from superset.views.tags import TagView # # Setup API views # appbuilder.add_api(AnnotationRestApi) appbuilder.add_api(AnnotationLayerRestApi) appbuilder.add_api(AsyncEventsRestApi) appbuilder.add_api(CacheRestApi) appbuilder.add_api(ChartRestApi) appbuilder.add_api(CssTemplateRestApi) appbuilder.add_api(DashboardRestApi) appbuilder.add_api(DatabaseRestApi) appbuilder.add_api(DatasetRestApi) appbuilder.add_api(DatasetColumnsRestApi) appbuilder.add_api(DatasetMetricRestApi) appbuilder.add_api(QueryRestApi) appbuilder.add_api(SavedQueryRestApi) appbuilder.add_api(ReportScheduleRestApi) appbuilder.add_api(ReportExecutionLogRestApi) # # Setup regular views # appbuilder.add_link( "Home", label=__("Home"), href="/superset/welcome/", cond=lambda: bool(appbuilder.app.config["LOGO_TARGET_PATH"]), ) appbuilder.add_view( AnnotationLayerModelView, "Annotation Layers", label=__("Annotation Layers"), icon="fa-comment", category="Manage", category_label=__("Manage"), category_icon="", ) appbuilder.add_view( DashboardModelView, "Dashboards", label=__("Dashboards"), icon="fa-dashboard", category="", category_icon="", ) appbuilder.add_view( SliceModelView, "Charts", label=__("Charts"), icon="fa-bar-chart", category="", category_icon="", ) appbuilder.add_view( DynamicPluginsView, "Plugins", label=__("Plugins"), category="Manage", category_label=__("Manage"), icon="fa-puzzle-piece", menu_cond=lambda: feature_flag_manager.is_feature_enabled( "DYNAMIC_PLUGINS"), ) appbuilder.add_view( CssTemplateModelView, "CSS Templates", label=__("CSS Templates"), icon="fa-css3", category="Manage", category_label=__("Manage"), category_icon="", ) appbuilder.add_view( RowLevelSecurityFiltersModelView, "Row Level Security", label=__("Row level security"), category="Security", category_label=__("Security"), icon="fa-lock", menu_cond=lambda: feature_flag_manager.is_feature_enabled( "ROW_LEVEL_SECURITY"), ) # # Setup views with no menu # appbuilder.add_view_no_menu(Api) appbuilder.add_view_no_menu(CssTemplateAsyncModelView) appbuilder.add_view_no_menu(CsvToDatabaseView) appbuilder.add_view_no_menu(ExcelToDatabaseView) appbuilder.add_view_no_menu(Dashboard) appbuilder.add_view_no_menu(DashboardModelViewAsync) appbuilder.add_view_no_menu(Datasource) appbuilder.add_view_no_menu(KV) appbuilder.add_view_no_menu(R) appbuilder.add_view_no_menu(SavedQueryView) appbuilder.add_view_no_menu(SavedQueryViewApi) appbuilder.add_view_no_menu(SliceAsync) appbuilder.add_view_no_menu(SqlLab) appbuilder.add_view_no_menu(SqlMetricInlineView) appbuilder.add_view_no_menu(AnnotationModelView) appbuilder.add_view_no_menu(Superset) appbuilder.add_view_no_menu(TableColumnInlineView) appbuilder.add_view_no_menu(TableModelView) appbuilder.add_view_no_menu(TableSchemaView) appbuilder.add_view_no_menu(TabStateView) appbuilder.add_view_no_menu(TagView) # # Add links # appbuilder.add_link( "Import Dashboards", label=__("Import Dashboards"), href="/superset/import_dashboards/", icon="fa-cloud-upload", category="Manage", category_label=__("Manage"), category_icon="fa-wrench", cond=lambda: not feature_flag_manager.is_feature_enabled( "VERSIONED_EXPORT"), ) appbuilder.add_link( "SQL Editor", label=_("SQL Editor"), href="/superset/sqllab/", category_icon="fa-flask", icon="fa-flask", category="SQL Lab", category_label=__("SQL Lab"), ) appbuilder.add_link( __("Saved Queries"), href="/savedqueryview/list/", icon="fa-save", category="SQL Lab", ) appbuilder.add_link( "Query Search", label=_("Query History"), href="/superset/sqllab/history/", icon="fa-search", category_icon="fa-flask", category="SQL Lab", category_label=__("SQL Lab"), ) appbuilder.add_view( DatabaseView, "Databases", label=__("Databases"), icon="fa-database", category="Data", category_label=__("Data"), category_icon="fa-database", ) appbuilder.add_link( "Datasets", label=__("Datasets"), href="/tablemodelview/list/", icon="fa-table", category="Data", category_label=__("Data"), category_icon="fa-table", ) appbuilder.add_separator("Data") appbuilder.add_link( "Upload a CSV", label=__("Upload a CSV"), href="/csvtodatabaseview/form", icon="fa-upload", category="Data", category_label=__("Data"), category_icon="fa-wrench", cond=lambda: bool(self.config["CSV_EXTENSIONS"].intersection( self.config["ALLOWED_EXTENSIONS"])), ) try: import xlrd # pylint: disable=unused-import appbuilder.add_link( "Upload Excel", label=__("Upload Excel"), href="/exceltodatabaseview/form", icon="fa-upload", category="Data", category_label=__("Data"), category_icon="fa-wrench", cond=lambda: bool(self.config["EXCEL_EXTENSIONS"].intersection( self.config["ALLOWED_EXTENSIONS"])), ) except ImportError: pass appbuilder.add_api(LogRestApi) appbuilder.add_view( LogModelView, "Action Log", label=__("Action Log"), category="Security", category_label=__("Security"), icon="fa-list-ol", menu_cond=lambda: (self.config["FAB_ADD_SECURITY_VIEWS"] and self. config["SUPERSET_LOG_VIEW"]), ) appbuilder.add_api(SecurityRestApi) # # Conditionally setup email views # if self.config["ENABLE_SCHEDULED_EMAIL_REPORTS"]: logging.warning( "ENABLE_SCHEDULED_EMAIL_REPORTS " "is deprecated and will be removed in version 2.0.0") appbuilder.add_separator( "Manage", cond=lambda: self.config["ENABLE_SCHEDULED_EMAIL_REPORTS"]) appbuilder.add_view( DashboardEmailScheduleView, "Dashboard Email Schedules", label=__("Dashboard Emails"), category="Manage", category_label=__("Manage"), icon="fa-search", menu_cond=lambda: self.config["ENABLE_SCHEDULED_EMAIL_REPORTS"], ) appbuilder.add_view( SliceEmailScheduleView, "Chart Emails", label=__("Chart Email Schedules"), category="Manage", category_label=__("Manage"), icon="fa-search", menu_cond=lambda: self.config["ENABLE_SCHEDULED_EMAIL_REPORTS"], ) if self.config["ENABLE_ALERTS"]: logging.warning( "ENABLE_ALERTS is deprecated and will be removed in version 2.0.0" ) appbuilder.add_view( AlertModelView, "Alerts", label=__("Alerts"), category="Manage", category_label=__("Manage"), icon="fa-exclamation-triangle", menu_cond=lambda: bool(self.config["ENABLE_ALERTS"]), ) appbuilder.add_view_no_menu(AlertLogModelView) appbuilder.add_view_no_menu(AlertObservationModelView) appbuilder.add_view( AlertView, "Alerts & Report", label=__("Alerts & Reports"), category="Manage", category_label=__("Manage"), icon="fa-exclamation-triangle", menu_cond=lambda: feature_flag_manager.is_feature_enabled( "ALERT_REPORTS"), ) appbuilder.add_view_no_menu(ReportView) appbuilder.add_view( AccessRequestsModelView, "Access requests", label=__("Access requests"), category="Security", category_label=__("Security"), icon="fa-table", menu_cond=lambda: bool(self.config["ENABLE_ACCESS_REQUEST"]), ) # # Druid Views # appbuilder.add_separator( "Data", cond=lambda: bool(self.config["DRUID_IS_ACTIVE"])) appbuilder.add_view( DruidDatasourceModelView, "Druid Datasources", label=__("Druid Datasources"), category="Data", category_label=__("Data"), icon="fa-cube", menu_cond=lambda: bool(self.config["DRUID_IS_ACTIVE"]), ) appbuilder.add_view( DruidClusterModelView, name="Druid Clusters", label=__("Druid Clusters"), icon="fa-cubes", category="Data", category_label=__("Data"), category_icon="fa-database", menu_cond=lambda: bool(self.config["DRUID_IS_ACTIVE"]), ) appbuilder.add_view_no_menu(DruidMetricInlineView) appbuilder.add_view_no_menu(DruidColumnInlineView) appbuilder.add_view_no_menu(Druid) appbuilder.add_link( "Scan New Datasources", label=__("Scan New Datasources"), href="/druid/scan_new_datasources/", category="Data", category_label=__("Data"), category_icon="fa-database", icon="fa-refresh", cond=lambda: bool(self.config["DRUID_IS_ACTIVE"] and self.config[ "DRUID_METADATA_LINKS_ENABLED"]), ) appbuilder.add_link( "Refresh Druid Metadata", label=__("Refresh Druid Metadata"), href="/druid/refresh_datasources/", category="Data", category_label=__("Data"), category_icon="fa-database", icon="fa-cog", cond=lambda: bool(self.config["DRUID_IS_ACTIVE"] and self.config[ "DRUID_METADATA_LINKS_ENABLED"]), ) appbuilder.add_separator( "Data", cond=lambda: bool(self.config["DRUID_IS_ACTIVE"]))
from superset.extensions import cache_manager, feature_flag_manager, security_manager from superset.legacy import update_time_range 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.superset_typing import FormData from superset.utils.core import DatasourceType from superset.utils.decorators import stats_timing from superset.viz import BaseViz logger = logging.getLogger(__name__) stats_logger = app.config["STATS_LOGGER"] REJECTED_FORM_DATA_KEYS: List[str] = [] if not feature_flag_manager.is_feature_enabled("ENABLE_JAVASCRIPT_CONTROLS"): REJECTED_FORM_DATA_KEYS = [ "js_tooltip", "js_onclick_href", "js_data_mutator" ] def sanitize_datasource_data( datasource_data: Dict[str, Any]) -> Dict[str, Any]: if datasource_data: datasource_database = datasource_data.get("database") if datasource_database: datasource_database["parameters"] = {} return datasource_data
def list(self) -> FlaskResponse: if not (app.config["ENABLE_REACT_CRUD_VIEWS"] and feature_flag_manager.is_feature_enabled("SIP_34_DATABASE_UI")): return super().list() return super().render_app_template()