mirror of https://github.com/apache/superset.git
Co-authored-by: Bogdan Kyryliuk <bogdankyryliuk@dropbox.com>
This commit is contained in:
parent
eac6fdcd29
commit
44654e5abc
|
@ -17,7 +17,7 @@
|
||||||
import json
|
import json
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
from flask import abort, request
|
from flask import abort, g, request
|
||||||
from flask_appbuilder import expose
|
from flask_appbuilder import expose
|
||||||
from flask_login import AnonymousUserMixin, LoginManager
|
from flask_login import AnonymousUserMixin, LoginManager
|
||||||
from flask_wtf.csrf import same_origin
|
from flask_wtf.csrf import same_origin
|
||||||
|
@ -77,7 +77,7 @@ class EmbeddedView(BaseSupersetView):
|
||||||
)
|
)
|
||||||
|
|
||||||
bootstrap_data = {
|
bootstrap_data = {
|
||||||
"common": common_bootstrap_payload(),
|
"common": common_bootstrap_payload(g.user),
|
||||||
"embedded": {
|
"embedded": {
|
||||||
"dashboard_id": embedded.dashboard_id,
|
"dashboard_id": embedded.dashboard_id,
|
||||||
},
|
},
|
||||||
|
|
|
@ -39,6 +39,7 @@ from flask_appbuilder import BaseView, Model, ModelView
|
||||||
from flask_appbuilder.actions import action
|
from flask_appbuilder.actions import action
|
||||||
from flask_appbuilder.forms import DynamicForm
|
from flask_appbuilder.forms import DynamicForm
|
||||||
from flask_appbuilder.models.sqla.filters import BaseFilter
|
from flask_appbuilder.models.sqla.filters import BaseFilter
|
||||||
|
from flask_appbuilder.security.sqla.models import User
|
||||||
from flask_appbuilder.widgets import ListWidget
|
from flask_appbuilder.widgets import ListWidget
|
||||||
from flask_babel import get_locale, gettext as __, lazy_gettext as _
|
from flask_babel import get_locale, gettext as __, lazy_gettext as _
|
||||||
from flask_jwt_extended.exceptions import NoAuthorizationError
|
from flask_jwt_extended.exceptions import NoAuthorizationError
|
||||||
|
@ -71,6 +72,7 @@ from superset.exceptions import (
|
||||||
SupersetException,
|
SupersetException,
|
||||||
SupersetSecurityException,
|
SupersetSecurityException,
|
||||||
)
|
)
|
||||||
|
from superset.extensions import cache_manager
|
||||||
from superset.models.helpers import ImportExportMixin
|
from superset.models.helpers import ImportExportMixin
|
||||||
from superset.reports.models import ReportRecipientType
|
from superset.reports.models import ReportRecipientType
|
||||||
from superset.superset_typing import FlaskResponse
|
from superset.superset_typing import FlaskResponse
|
||||||
|
@ -284,7 +286,7 @@ class BaseSupersetView(BaseView):
|
||||||
def render_app_template(self) -> FlaskResponse:
|
def render_app_template(self) -> FlaskResponse:
|
||||||
payload = {
|
payload = {
|
||||||
"user": bootstrap_user_data(g.user, include_perms=True),
|
"user": bootstrap_user_data(g.user, include_perms=True),
|
||||||
"common": common_bootstrap_payload(),
|
"common": common_bootstrap_payload(g.user),
|
||||||
}
|
}
|
||||||
return self.render_template(
|
return self.render_template(
|
||||||
"superset/spa.html",
|
"superset/spa.html",
|
||||||
|
@ -295,7 +297,7 @@ class BaseSupersetView(BaseView):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def menu_data() -> Dict[str, Any]:
|
def menu_data(user: User) -> Dict[str, Any]:
|
||||||
menu = appbuilder.menu.get_data()
|
menu = appbuilder.menu.get_data()
|
||||||
|
|
||||||
languages = {}
|
languages = {}
|
||||||
|
@ -340,22 +342,27 @@ def menu_data() -> Dict[str, Any]:
|
||||||
"build_number": build_number,
|
"build_number": build_number,
|
||||||
"languages": languages,
|
"languages": languages,
|
||||||
"show_language_picker": len(languages.keys()) > 1,
|
"show_language_picker": len(languages.keys()) > 1,
|
||||||
"user_is_anonymous": g.user.is_anonymous,
|
"user_is_anonymous": user.is_anonymous,
|
||||||
"user_info_url": None
|
"user_info_url": None
|
||||||
if appbuilder.app.config["MENU_HIDE_USER_INFO"]
|
if appbuilder.app.config["MENU_HIDE_USER_INFO"]
|
||||||
else appbuilder.get_url_for_userinfo,
|
else appbuilder.get_url_for_userinfo,
|
||||||
"user_logout_url": appbuilder.get_url_for_logout,
|
"user_logout_url": appbuilder.get_url_for_logout,
|
||||||
"user_login_url": appbuilder.get_url_for_login,
|
"user_login_url": appbuilder.get_url_for_login,
|
||||||
"user_profile_url": None
|
"user_profile_url": None
|
||||||
if g.user.is_anonymous or appbuilder.app.config["MENU_HIDE_USER_INFO"]
|
if user.is_anonymous or appbuilder.app.config["MENU_HIDE_USER_INFO"]
|
||||||
else f"/superset/profile/{g.user.username}",
|
else f"/superset/profile/{user.username}",
|
||||||
"locale": session.get("locale", "en"),
|
"locale": session.get("locale", "en"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def common_bootstrap_payload() -> Dict[str, Any]:
|
@cache_manager.cache.memoize(timeout=60)
|
||||||
"""Common data always sent to the client"""
|
def common_bootstrap_payload(user: User) -> Dict[str, Any]:
|
||||||
|
"""Common data always sent to the client
|
||||||
|
|
||||||
|
The function is memoized as the return value only changes based
|
||||||
|
on configuration and feature flag values.
|
||||||
|
"""
|
||||||
messages = get_flashed_messages(with_categories=True)
|
messages = get_flashed_messages(with_categories=True)
|
||||||
locale = str(get_locale())
|
locale = str(get_locale())
|
||||||
|
|
||||||
|
@ -388,7 +395,7 @@ def common_bootstrap_payload() -> Dict[str, Any]:
|
||||||
"extra_sequential_color_schemes": conf["EXTRA_SEQUENTIAL_COLOR_SCHEMES"],
|
"extra_sequential_color_schemes": conf["EXTRA_SEQUENTIAL_COLOR_SCHEMES"],
|
||||||
"extra_categorical_color_schemes": conf["EXTRA_CATEGORICAL_COLOR_SCHEMES"],
|
"extra_categorical_color_schemes": conf["EXTRA_CATEGORICAL_COLOR_SCHEMES"],
|
||||||
"theme_overrides": conf["THEME_OVERRIDES"],
|
"theme_overrides": conf["THEME_OVERRIDES"],
|
||||||
"menu_data": menu_data(),
|
"menu_data": menu_data(user),
|
||||||
}
|
}
|
||||||
bootstrap_data.update(conf["COMMON_BOOTSTRAP_OVERRIDES_FUNC"](bootstrap_data))
|
bootstrap_data.update(conf["COMMON_BOOTSTRAP_OVERRIDES_FUNC"](bootstrap_data))
|
||||||
return bootstrap_data
|
return bootstrap_data
|
||||||
|
@ -499,7 +506,7 @@ def show_unexpected_exception(ex: Exception) -> FlaskResponse:
|
||||||
def get_common_bootstrap_data() -> Dict[str, Any]:
|
def get_common_bootstrap_data() -> Dict[str, Any]:
|
||||||
def serialize_bootstrap_data() -> str:
|
def serialize_bootstrap_data() -> str:
|
||||||
return json.dumps(
|
return json.dumps(
|
||||||
{"common": common_bootstrap_payload()},
|
{"common": common_bootstrap_payload(g.user)},
|
||||||
default=utils.pessimistic_json_iso_dttm_ser,
|
default=utils.pessimistic_json_iso_dttm_ser,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -517,7 +524,7 @@ class SupersetModelView(ModelView):
|
||||||
def render_app_template(self) -> FlaskResponse:
|
def render_app_template(self) -> FlaskResponse:
|
||||||
payload = {
|
payload = {
|
||||||
"user": bootstrap_user_data(g.user, include_perms=True),
|
"user": bootstrap_user_data(g.user, include_perms=True),
|
||||||
"common": common_bootstrap_payload(),
|
"common": common_bootstrap_payload(g.user),
|
||||||
}
|
}
|
||||||
return self.render_template(
|
return self.render_template(
|
||||||
"superset/spa.html",
|
"superset/spa.html",
|
||||||
|
|
|
@ -928,7 +928,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
||||||
"force": force,
|
"force": force,
|
||||||
"user": bootstrap_user_data(g.user, include_perms=True),
|
"user": bootstrap_user_data(g.user, include_perms=True),
|
||||||
"forced_height": request.args.get("height"),
|
"forced_height": request.args.get("height"),
|
||||||
"common": common_bootstrap_payload(),
|
"common": common_bootstrap_payload(g.user),
|
||||||
}
|
}
|
||||||
if slc:
|
if slc:
|
||||||
title = slc.slice_name
|
title = slc.slice_name
|
||||||
|
@ -1932,7 +1932,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
||||||
|
|
||||||
bootstrap_data = {
|
bootstrap_data = {
|
||||||
"user": bootstrap_user_data(g.user, include_perms=True),
|
"user": bootstrap_user_data(g.user, include_perms=True),
|
||||||
"common": common_bootstrap_payload(),
|
"common": common_bootstrap_payload(g.user),
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.render_template(
|
return self.render_template(
|
||||||
|
@ -2673,7 +2673,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"user": bootstrap_user_data(g.user, include_perms=True),
|
"user": bootstrap_user_data(g.user, include_perms=True),
|
||||||
"common": common_bootstrap_payload(),
|
"common": common_bootstrap_payload(g.user),
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.render_template(
|
return self.render_template(
|
||||||
|
@ -2702,7 +2702,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"user": bootstrap_user_data(user, include_perms=True),
|
"user": bootstrap_user_data(user, include_perms=True),
|
||||||
"common": common_bootstrap_payload(),
|
"common": common_bootstrap_payload(g.user),
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.render_template(
|
return self.render_template(
|
||||||
|
@ -2766,7 +2766,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
||||||
"""SQL Editor"""
|
"""SQL Editor"""
|
||||||
payload = {
|
payload = {
|
||||||
"defaultDbId": config["SQLLAB_DEFAULT_DBID"],
|
"defaultDbId": config["SQLLAB_DEFAULT_DBID"],
|
||||||
"common": common_bootstrap_payload(),
|
"common": common_bootstrap_payload(g.user),
|
||||||
**self._get_sqllab_tabs(get_user_id()),
|
**self._get_sqllab_tabs(get_user_id()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@ class Dashboard(BaseSupersetView):
|
||||||
)
|
)
|
||||||
|
|
||||||
bootstrap_data = {
|
bootstrap_data = {
|
||||||
"common": common_bootstrap_payload(),
|
"common": common_bootstrap_payload(g.user),
|
||||||
"embedded": {"dashboard_id": dashboard_id_or_slug},
|
"embedded": {"dashboard_id": dashboard_id_or_slug},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ from superset.connectors.sqla.models import SqlaTable
|
||||||
from superset.db_engine_specs.base import BaseEngineSpec
|
from superset.db_engine_specs.base import BaseEngineSpec
|
||||||
from superset.db_engine_specs.mssql import MssqlEngineSpec
|
from superset.db_engine_specs.mssql import MssqlEngineSpec
|
||||||
from superset.exceptions import SupersetException
|
from superset.exceptions import SupersetException
|
||||||
from superset.extensions import async_query_manager
|
from superset.extensions import async_query_manager, cache_manager
|
||||||
from superset.models import core as models
|
from superset.models import core as models
|
||||||
from superset.models.annotations import Annotation, AnnotationLayer
|
from superset.models.annotations import Annotation, AnnotationLayer
|
||||||
from superset.models.dashboard import Dashboard
|
from superset.models.dashboard import Dashboard
|
||||||
|
@ -1434,6 +1434,8 @@ class TestCore(SupersetTestCase):
|
||||||
"""
|
"""
|
||||||
Functions in feature flags don't break bootstrap data serialization.
|
Functions in feature flags don't break bootstrap data serialization.
|
||||||
"""
|
"""
|
||||||
|
# feature flags are cached
|
||||||
|
cache_manager.cache.clear()
|
||||||
self.login()
|
self.login()
|
||||||
|
|
||||||
encoded = json.dumps(
|
encoded = json.dumps(
|
||||||
|
|
Loading…
Reference in New Issue