Skip to content
Merged
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*.pyc
*.sqllite
*.swp
.bento*
.cache-loader
.coverage
.DS_Store
Expand Down
2 changes: 2 additions & 0 deletions .rat-excludes
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ apache_superset.egg-info
.*json
.*csv
# Generated doc files
env/*
docs/_build/*
docs/_modules/*
_build/*
_static/*
.buildinfo
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ croniter==0.3.30
cryptography==2.7
decorator==4.4.0 # via retry
defusedxml==0.6.0 # via python3-openid
flask-appbuilder==2.2.1
flask-appbuilder==2.2.2rc3
flask-babel==0.12.2 # via flask-appbuilder
flask-caching==1.7.2
flask-compress==1.4.0
Expand Down
50 changes: 19 additions & 31 deletions superset/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,21 +149,15 @@ def init_views(self) -> None:
CssTemplateAsyncModelView,
)
from superset.views.chart.api import ChartRestApi
from superset.views.chart.views import SliceModelView, SliceAsync, SliceAddView
from superset.views.chart.views import SliceModelView, SliceAsync
from superset.views.dashboard.api import DashboardRestApi
from superset.views.dashboard.views import (
DashboardModelView,
Dashboard,
DashboardAddView,
DashboardModelViewAsync,
)
from superset.views.database.api import DatabaseRestApi
from superset.views.database.views import (
DatabaseView,
DatabaseTablesAsync,
CsvToDatabaseView,
DatabaseAsync,
)
from superset.views.database.views import DatabaseView, CsvToDatabaseView
from superset.views.datasource import Datasource
from superset.views.log.api import LogRestApi
from superset.views.log.views import LogModelView
Expand Down Expand Up @@ -218,6 +212,16 @@ def init_views(self) -> None:
category_label=__("Sources"),
category_icon="fa-database",
)
appbuilder.add_link(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

side mission: fix the menu ordering

"Tables",
label=__("Tables"),
href="/tablemodelview/list/?_flt_1_is_sqllab_view=y",
icon="fa-table",
category="Sources",
category_label=__("Sources"),
category_icon="fa-table",
)
appbuilder.add_separator("Sources")
appbuilder.add_view(
SliceModelView,
"Charts",
Expand Down Expand Up @@ -259,16 +263,12 @@ def init_views(self) -> None:
appbuilder.add_view_no_menu(CssTemplateAsyncModelView)
appbuilder.add_view_no_menu(CsvToDatabaseView)
appbuilder.add_view_no_menu(Dashboard)
appbuilder.add_view_no_menu(DashboardAddView)
appbuilder.add_view_no_menu(DashboardModelViewAsync)
appbuilder.add_view_no_menu(DatabaseAsync)
appbuilder.add_view_no_menu(DatabaseTablesAsync)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 2 are unused now...

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(SliceAddView)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merged with SliceAsync to simplify

appbuilder.add_view_no_menu(SliceAsync)
appbuilder.add_view_no_menu(SqlLab)
appbuilder.add_view_no_menu(SqlMetricInlineView)
Expand All @@ -282,12 +282,6 @@ def init_views(self) -> None:
#
# Add links
#
appbuilder.add_link(
__("Saved Queries"),
href="/sqllab/my_queries/",
icon="fa-save",
category="SQL Lab",
)
appbuilder.add_link(
"Import Dashboards",
label=__("Import Dashboards"),
Expand All @@ -306,6 +300,12 @@ def init_views(self) -> None:
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"),
Expand All @@ -324,23 +324,11 @@ def init_views(self) -> None:
category_label=__("Sources"),
category_icon="fa-wrench",
)
appbuilder.add_link(
"Tables",
label=__("Tables"),
href="/tablemodelview/list/?_flt_1_is_sqllab_view=y",
icon="fa-table",
category="Sources",
category_label=__("Sources"),
category_icon="fa-table",
)

#
# Conditionally setup log views
#
if (
not self.config["FAB_ADD_SECURITY_VIEWS"] is False
or self.config["SUPERSET_LOG_VIEW"] is False
):
if self.config["FAB_ADD_SECURITY_VIEWS"] and self.config["SUPERSET_LOG_VIEW"]:
appbuilder.add_api(LogRestApi)
appbuilder.add_view(
LogModelView,
Expand Down
2 changes: 1 addition & 1 deletion superset/assets/src/dashboard/actions/sliceEntities.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function fetchAllSlices(userId) {
dispatch(fetchAllSlicesStarted());

return SupersetClient.get({
endpoint: `/sliceaddview/api/read?_flt_0_created_by=${userId}`,
endpoint: `/sliceasync/api/read?_flt_0_created_by=${userId}`,
})
.then(({ json }) => {
const slices = {};
Expand Down
7 changes: 5 additions & 2 deletions superset/connectors/druid/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from superset import app, appbuilder, db, security_manager
from superset.connectors.base.views import DatasourceModelView
from superset.connectors.connector_registry import ConnectorRegistry
from superset.constants import RouteMethod
from superset.utils import core as utils
from superset.views.base import (
BaseSupersetView,
Expand All @@ -47,6 +48,7 @@

class DruidColumnInlineView(CompactCRUDMixin, SupersetModelView):
datamodel = SQLAInterface(models.DruidColumn)
include_route_methods = RouteMethod.RELATED_VIEW_SET

list_title = _("Columns")
show_title = _("Show Druid Column")
Expand Down Expand Up @@ -133,6 +135,7 @@ def post_add(self, col):

class DruidMetricInlineView(CompactCRUDMixin, SupersetModelView):
datamodel = SQLAInterface(models.DruidMetric)
include_route_methods = RouteMethod.RELATED_VIEW_SET

list_title = _("Metrics")
show_title = _("Show Druid Metric")
Expand Down Expand Up @@ -185,7 +188,7 @@ class DruidMetricInlineView(CompactCRUDMixin, SupersetModelView):

class DruidClusterModelView(SupersetModelView, DeleteMixin, YamlExportMixin):
datamodel = SQLAInterface(models.DruidCluster)

include_route_methods = RouteMethod.CRUD_SET
list_title = _("Druid Clusters")
show_title = _("Show Druid Cluster")
add_title = _("Add Druid Cluster")
Expand Down Expand Up @@ -255,7 +258,7 @@ def _delete(self, pk):

class DruidDatasourceModelView(DatasourceModelView, DeleteMixin, YamlExportMixin):
datamodel = SQLAInterface(models.DruidDatasource)

include_route_methods = RouteMethod.CRUD_SET
list_title = _("Druid Datasources")
show_title = _("Show Druid Datasource")
add_title = _("Add Druid Datasource")
Expand Down
5 changes: 5 additions & 0 deletions superset/connectors/sqla/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

from superset import appbuilder, db, security_manager
from superset.connectors.base.views import DatasourceModelView
from superset.constants import RouteMethod
from superset.utils import core as utils
from superset.views.base import (
DatasourceFilter,
Expand All @@ -48,6 +49,8 @@

class TableColumnInlineView(CompactCRUDMixin, SupersetModelView):
datamodel = SQLAInterface(models.TableColumn)
# TODO TODO, review need for this on related_views
include_route_methods = RouteMethod.RELATED_VIEW_SET

list_title = _("Columns")
show_title = _("Show Column")
Expand Down Expand Up @@ -164,6 +167,7 @@ class TableColumnInlineView(CompactCRUDMixin, SupersetModelView):

class SqlMetricInlineView(CompactCRUDMixin, SupersetModelView):
datamodel = SQLAInterface(models.SqlMetric)
include_route_methods = RouteMethod.RELATED_VIEW_SET

list_title = _("Metrics")
show_title = _("Show Metric")
Expand Down Expand Up @@ -223,6 +227,7 @@ class SqlMetricInlineView(CompactCRUDMixin, SupersetModelView):

class TableModelView(DatasourceModelView, DeleteMixin, YamlExportMixin):
datamodel = SQLAInterface(models.SqlaTable)
include_route_methods = RouteMethod.CRUD_SET

list_title = _("Tables")
show_title = _("Show Table")
Expand Down
40 changes: 40 additions & 0 deletions superset/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,43 @@

# string to use when None values *need* to be converted to/from strings
NULL_STRING = "<NULL>"


class RouteMethod: # pylint: disable=too-few-public-methods
"""
Route methods are a FAB concept around ModelView and RestModelView
classes in FAB. Derivatives can define `include_route_method` and
`exclude_route_methods` class attribute as a set of methods that
will or won't get exposed.

This class is a collection of static constants to reference common
route methods, namely the ones defined in the base classes in FAB
"""

# ModelView specific
ACTION = "action"
ACTION_POST = "action_post"
ADD = "add"
API_CREATE = "api_create"
API_DELETE = "api_delete"
API_GET = "api_get"
API_READ = "api_read"
API_UPDATE = "api_update"
DELETE = "delete"
DOWNLOAD = "download"
EDIT = "edit"
LIST = "list"
SHOW = "show"

# RestModelView specific
EXPORT = "export"
GET = "get"
GET_LIST = "get_list"
POST = "post"
PUT = "put"
RELATED = "related"

# Commonly used sets
CRUD_SET = {ADD, LIST, EDIT, DELETE, ACTION_POST}
RELATED_VIEW_SET = {ADD, LIST, EDIT, DELETE}
REST_MODEL_VIEW_CRUD_SET = {DELETE, GET, GET_LIST, POST, PUT}
10 changes: 10 additions & 0 deletions superset/security/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
PermissionViewModelView,
RoleModelView,
UserModelView,
ViewMenuModelView,
)
from flask_appbuilder.widgets import ListWidget
from sqlalchemy import or_
Expand All @@ -40,6 +41,7 @@

from superset import sql_parse
from superset.connectors.connector_registry import ConnectorRegistry
from superset.constants import RouteMethod
from superset.exceptions import SupersetSecurityException
from superset.utils.core import DatasourceName

Expand Down Expand Up @@ -76,8 +78,16 @@ def __init__(self, **kwargs):
PermissionViewModelView.list_widget = SupersetSecurityListWidget
PermissionModelView.list_widget = SupersetSecurityListWidget

# Limiting routes on FAB model views
UserModelView.include_route_methods = RouteMethod.CRUD_SET | {"userinfo"}
RoleModelView.include_route_methods = RouteMethod.CRUD_SET
PermissionViewModelView.include_route_methods = {RouteMethod.LIST}
PermissionModelView.include_route_methods = {RouteMethod.LIST}
ViewMenuModelView.include_route_methods = {RouteMethod.LIST}


class SupersetSecurityManager(SecurityManager):
userstatschartview = None
READ_ONLY_MODEL_VIEWS = {"DatabaseAsync", "DatabaseView", "DruidClusterModelView"}

USER_MODEL_VIEWS = {
Expand Down
3 changes: 3 additions & 0 deletions superset/views/annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from flask_babel import lazy_gettext as _
from wtforms.validators import StopValidation

from superset.constants import RouteMethod
from superset.models.annotations import Annotation, AnnotationLayer

from .base import DeleteMixin, SupersetModelView
Expand Down Expand Up @@ -45,6 +46,7 @@ class AnnotationModelView(
SupersetModelView, DeleteMixin
): # pylint: disable=too-many-ancestors
datamodel = SQLAInterface(Annotation)
include_route_methods = RouteMethod.CRUD_SET

list_title = _("List Annotation")
show_title = _("Show Annotation")
Expand Down Expand Up @@ -93,6 +95,7 @@ class AnnotationLayerModelView(
SupersetModelView, DeleteMixin
): # pylint: disable=too-many-ancestors
datamodel = SQLAInterface(AnnotationLayer)
include_route_methods = RouteMethod.CRUD_SET

list_title = _("List Annotation Layer")
show_title = _("Show Annotation Layer")
Expand Down
11 changes: 11 additions & 0 deletions superset/views/base_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ class BaseSupersetModelRestApi(ModelRestApi):
"""

logger = logging.getLogger(__name__)
method_permission_name = {
"get_list": "list",
"get": "show",
"export": "mulexport",
"post": "add",
"put": "edit",
"delete": "delete",
"bulk_delete": "delete",
"info": "list",
"related": "list",
}

order_rel_fields: Dict[str, Tuple[str, str]] = {}
"""
Expand Down
9 changes: 0 additions & 9 deletions superset/views/chart/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,6 @@ class ChartRestApi(SliceMixin, BaseOwnedModelRestApi):
allow_browser_login = True

class_permission_name = "SliceModelView"
method_permission_name = {
"get_list": "list",
"get": "show",
"post": "add",
"put": "edit",
"delete": "delete",
"info": "list",
"related": "list",
}
show_columns = [
"slice_name",
"description",
Expand Down
Loading