diff --git a/superset/initialization/__init__.py b/superset/initialization/__init__.py index 4398c0c6be75b..61205f38dfbd8 100644 --- a/superset/initialization/__init__.py +++ b/superset/initialization/__init__.py @@ -187,6 +187,7 @@ def init_views(self) -> None: from superset.views.redirects import R from superset.views.sql_lab.views import ( SavedQueryView, + SavedQueryViewApi, SqlLab, TableSchemaView, TabStateView, @@ -312,6 +313,7 @@ def init_views(self) -> None: appbuilder.add_view_no_menu(R) appbuilder.add_view_no_menu(ProfileView) 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) diff --git a/superset/views/sql_lab/views.py b/superset/views/sql_lab/views.py index 62558f5ab524f..f07705bac3f42 100644 --- a/superset/views/sql_lab/views.py +++ b/superset/views/sql_lab/views.py @@ -19,16 +19,23 @@ import simplejson as json from flask import redirect, request, Response from flask_appbuilder import expose +from flask_appbuilder.models.sqla.interface import SQLAInterface from flask_appbuilder.security.decorators import has_access, has_access_api from flask_babel import lazy_gettext as _ from sqlalchemy import and_ from superset import db -from superset.models.sql_lab import Query, TableSchema, TabState +from superset.constants import MODEL_VIEW_RW_METHOD_PERMISSION_MAP, RouteMethod +from superset.models.sql_lab import Query, SavedQuery, TableSchema, TabState from superset.superset_typing import FlaskResponse from superset.utils import core as utils from superset.utils.core import get_user_id -from superset.views.base import BaseSupersetView, json_success +from superset.views.base import ( + BaseSupersetView, + DeleteMixin, + json_success, + SupersetModelView, +) logger = logging.getLogger(__name__) @@ -43,6 +50,33 @@ def list(self) -> FlaskResponse: return super().render_app_template() +class SavedQueryViewApi( + SupersetModelView, DeleteMixin +): # pylint: disable=too-many-ancestors + datamodel = SQLAInterface(SavedQuery) + include_route_methods = RouteMethod.CRUD_SET + route_base = "/savedqueryviewapi" + class_permission_name = "SavedQuery" + + include_route_methods = { + RouteMethod.API_READ, + RouteMethod.API_CREATE, + RouteMethod.API_UPDATE, + RouteMethod.API_GET, + } + + method_permission_name = MODEL_VIEW_RW_METHOD_PERMISSION_MAP + + add_columns = ["label", "db_id", "schema", "description", "sql", "extra_json"] + edit_columns = add_columns + show_columns = add_columns + ["id"] + + @has_access_api + @expose("show/") + def show(self, pk: int) -> FlaskResponse: + return super().show(pk) + + def _get_owner_id(tab_state_id: int) -> int: return db.session.query(TabState.user_id).filter_by(id=tab_state_id).scalar()