mirror of https://github.com/apache/superset.git
Make g.user attribute access safe for public users (#14287)
This commit is contained in:
parent
7ff35dfdfb
commit
6875a1a9e2
|
@ -954,7 +954,7 @@ class ChartRestApi(BaseSupersetModelRestApi):
|
||||||
charts = ChartDAO.find_by_ids(requested_ids)
|
charts = ChartDAO.find_by_ids(requested_ids)
|
||||||
if not charts:
|
if not charts:
|
||||||
return self.response_404()
|
return self.response_404()
|
||||||
favorited_chart_ids = ChartDAO.favorited_ids(charts, g.user.id)
|
favorited_chart_ids = ChartDAO.favorited_ids(charts, g.user.get_id())
|
||||||
res = [
|
res = [
|
||||||
{"id": request_id, "value": request_id in favorited_chart_ids}
|
{"id": request_id, "value": request_id in favorited_chart_ids}
|
||||||
for request_id in requested_ids
|
for request_id in requested_ids
|
||||||
|
|
|
@ -409,7 +409,7 @@ FEATURE_FLAGS: Dict[str, bool] = {}
|
||||||
# from flask import g, request
|
# from flask import g, request
|
||||||
# def GET_FEATURE_FLAGS_FUNC(feature_flags_dict: Dict[str, bool]) -> Dict[str, bool]:
|
# def GET_FEATURE_FLAGS_FUNC(feature_flags_dict: Dict[str, bool]) -> Dict[str, bool]:
|
||||||
# if hasattr(g, "user") and g.user.is_active:
|
# if hasattr(g, "user") and g.user.is_active:
|
||||||
# feature_flags_dict['some_feature'] = g.user and g.user.id == 5
|
# feature_flags_dict['some_feature'] = g.user and g.user.get_id() == 5
|
||||||
# return feature_flags_dict
|
# return feature_flags_dict
|
||||||
GET_FEATURE_FLAGS_FUNC: Optional[Callable[[Dict[str, bool]], Dict[str, bool]]] = None
|
GET_FEATURE_FLAGS_FUNC: Optional[Callable[[Dict[str, bool]], Dict[str, bool]]] = None
|
||||||
|
|
||||||
|
|
|
@ -826,7 +826,9 @@ class DashboardRestApi(BaseSupersetModelRestApi):
|
||||||
dashboards = DashboardDAO.find_by_ids(requested_ids)
|
dashboards = DashboardDAO.find_by_ids(requested_ids)
|
||||||
if not dashboards:
|
if not dashboards:
|
||||||
return self.response_404()
|
return self.response_404()
|
||||||
favorited_dashboard_ids = DashboardDAO.favorited_ids(dashboards, g.user.id)
|
favorited_dashboard_ids = DashboardDAO.favorited_ids(
|
||||||
|
dashboards, g.user.get_id()
|
||||||
|
)
|
||||||
res = [
|
res = [
|
||||||
{"id": request_id, "value": request_id in favorited_dashboard_ids}
|
{"id": request_id, "value": request_id in favorited_dashboard_ids}
|
||||||
for request_id in requested_ids
|
for request_id in requested_ids
|
||||||
|
|
|
@ -999,7 +999,7 @@ class BaseEngineSpec: # pylint: disable=too-many-public-methods
|
||||||
if not cls.get_allow_cost_estimate(extra):
|
if not cls.get_allow_cost_estimate(extra):
|
||||||
raise Exception("Database does not support cost estimation")
|
raise Exception("Database does not support cost estimation")
|
||||||
|
|
||||||
user_name = g.user.username if g.user else None
|
user_name = g.user.username if g.user and hasattr(g.user, "username") else None
|
||||||
parsed_query = sql_parse.ParsedQuery(sql)
|
parsed_query = sql_parse.ParsedQuery(sql)
|
||||||
statements = parsed_query.get_statements()
|
statements = parsed_query.get_statements()
|
||||||
|
|
||||||
|
|
|
@ -142,8 +142,8 @@ class ExtraCache:
|
||||||
|
|
||||||
if hasattr(g, "user") and g.user:
|
if hasattr(g, "user") and g.user:
|
||||||
if add_to_cache_keys:
|
if add_to_cache_keys:
|
||||||
self.cache_key_wrapper(g.user.id)
|
self.cache_key_wrapper(g.user.get_id())
|
||||||
return g.user.id
|
return g.user.get_id()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def current_username(self, add_to_cache_keys: bool = True) -> Optional[str]:
|
def current_username(self, add_to_cache_keys: bool = True) -> Optional[str]:
|
||||||
|
@ -154,7 +154,7 @@ class ExtraCache:
|
||||||
:returns: The username
|
:returns: The username
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if g.user:
|
if g.user and hasattr(g.user, "username"):
|
||||||
if add_to_cache_keys:
|
if add_to_cache_keys:
|
||||||
self.cache_key_wrapper(g.user.username)
|
self.cache_key_wrapper(g.user.username)
|
||||||
return g.user.username
|
return g.user.username
|
||||||
|
|
|
@ -434,7 +434,7 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
|
||||||
view_menu_names = (
|
view_menu_names = (
|
||||||
base_query.join(assoc_user_role)
|
base_query.join(assoc_user_role)
|
||||||
.join(self.user_model)
|
.join(self.user_model)
|
||||||
.filter(self.user_model.id == g.user.id)
|
.filter(self.user_model.id == g.user.get_id())
|
||||||
.filter(self.permission_model.name == permission_name)
|
.filter(self.permission_model.name == permission_name)
|
||||||
).all()
|
).all()
|
||||||
return {s.name for s in view_menu_names}
|
return {s.name for s in view_menu_names}
|
||||||
|
@ -1044,7 +1044,7 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods
|
||||||
|
|
||||||
user_roles = (
|
user_roles = (
|
||||||
self.get_session.query(assoc_user_role.c.role_id)
|
self.get_session.query(assoc_user_role.c.role_id)
|
||||||
.filter(assoc_user_role.c.user_id == g.user.id)
|
.filter(assoc_user_role.c.user_id == g.user.get_id())
|
||||||
.subquery()
|
.subquery()
|
||||||
)
|
)
|
||||||
regular_filter_roles = (
|
regular_filter_roles = (
|
||||||
|
|
|
@ -151,7 +151,7 @@ class PrestoDBSQLValidator(BaseSQLValidator):
|
||||||
For example, "SELECT 1 FROM default.mytable" becomes "EXPLAIN (TYPE
|
For example, "SELECT 1 FROM default.mytable" becomes "EXPLAIN (TYPE
|
||||||
VALIDATE) SELECT 1 FROM default.mytable.
|
VALIDATE) SELECT 1 FROM default.mytable.
|
||||||
"""
|
"""
|
||||||
user_name = g.user.username if g.user else None
|
user_name = g.user.username if g.user and hasattr(g.user, "username") else None
|
||||||
parsed_query = ParsedQuery(sql)
|
parsed_query = ParsedQuery(sql)
|
||||||
statements = parsed_query.get_statements()
|
statements = parsed_query.get_statements()
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,10 @@ class BaseFavoriteFilter(BaseFilter): # pylint: disable=too-few-public-methods
|
||||||
if security_manager.current_user is None:
|
if security_manager.current_user is None:
|
||||||
return query
|
return query
|
||||||
users_favorite_query = db.session.query(FavStar.obj_id).filter(
|
users_favorite_query = db.session.query(FavStar.obj_id).filter(
|
||||||
and_(FavStar.user_id == g.user.id, FavStar.class_name == self.class_name)
|
and_(
|
||||||
|
FavStar.user_id == g.user.get_id(),
|
||||||
|
FavStar.class_name == self.class_name,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if value:
|
if value:
|
||||||
return query.filter(and_(self.model.id.in_(users_favorite_query)))
|
return query.filter(and_(self.model.id.in_(users_favorite_query)))
|
||||||
|
|
|
@ -113,8 +113,8 @@ class BaseOwnedSchema(BaseSupersetSchema):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_owners(instance: Model, owners: List[int]) -> None:
|
def set_owners(instance: Model, owners: List[int]) -> None:
|
||||||
owner_objs = list()
|
owner_objs = list()
|
||||||
if g.user.id not in owners:
|
if g.user.get_id() not in owners:
|
||||||
owners.append(g.user.id)
|
owners.append(g.user.get_id())
|
||||||
for owner_id in owners:
|
for owner_id in owners:
|
||||||
user = current_app.appbuilder.get_session.query(
|
user = current_app.appbuilder.get_session.query(
|
||||||
current_app.appbuilder.sm.user_model
|
current_app.appbuilder.sm.user_model
|
||||||
|
|
|
@ -1067,8 +1067,10 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
||||||
views = [vn for vn in views if substr_parsed in get_datasource_label(vn)]
|
views = [vn for vn in views if substr_parsed in get_datasource_label(vn)]
|
||||||
|
|
||||||
if not schema_parsed and database.default_schemas:
|
if not schema_parsed and database.default_schemas:
|
||||||
user_schema = g.user.email.split("@")[0]
|
user_schemas = (
|
||||||
valid_schemas = set(database.default_schemas + [user_schema])
|
[g.user.email.split("@")[0]] if hasattr(g.user, "email") else []
|
||||||
|
)
|
||||||
|
valid_schemas = set(database.default_schemas + user_schemas)
|
||||||
|
|
||||||
tables = [tn for tn in tables if tn.schema in valid_schemas]
|
tables = [tn for tn in tables if tn.schema in valid_schemas]
|
||||||
views = [vn for vn in views if vn.schema in valid_schemas]
|
views = [vn for vn in views if vn.schema in valid_schemas]
|
||||||
|
@ -1261,7 +1263,9 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
||||||
database.set_sqlalchemy_uri(uri)
|
database.set_sqlalchemy_uri(uri)
|
||||||
database.db_engine_spec.mutate_db_for_connection_test(database)
|
database.db_engine_spec.mutate_db_for_connection_test(database)
|
||||||
|
|
||||||
username = g.user.username if g.user is not None else None
|
username = (
|
||||||
|
g.user.username if g.user and hasattr(g.user, "username") else None
|
||||||
|
)
|
||||||
engine = database.get_sqla_engine(user_name=username)
|
engine = database.get_sqla_engine(user_name=username)
|
||||||
|
|
||||||
with closing(engine.raw_connection()) as conn:
|
with closing(engine.raw_connection()) as conn:
|
||||||
|
@ -1515,7 +1519,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
||||||
) -> FlaskResponse:
|
) -> FlaskResponse:
|
||||||
"""List of slices a user owns, created, modified or faved"""
|
"""List of slices a user owns, created, modified or faved"""
|
||||||
if not user_id:
|
if not user_id:
|
||||||
user_id = g.user.id
|
user_id = g.user.get_id()
|
||||||
|
|
||||||
owner_ids_query = (
|
owner_ids_query = (
|
||||||
db.session.query(Slice.id)
|
db.session.query(Slice.id)
|
||||||
|
@ -1567,7 +1571,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
||||||
) -> FlaskResponse:
|
) -> FlaskResponse:
|
||||||
"""List of slices created by this user"""
|
"""List of slices created by this user"""
|
||||||
if not user_id:
|
if not user_id:
|
||||||
user_id = g.user.id
|
user_id = g.user.get_id()
|
||||||
qry = (
|
qry = (
|
||||||
db.session.query(Slice)
|
db.session.query(Slice)
|
||||||
.filter(or_(Slice.created_by_fk == user_id, Slice.changed_by_fk == user_id))
|
.filter(or_(Slice.created_by_fk == user_id, Slice.changed_by_fk == user_id))
|
||||||
|
@ -1595,7 +1599,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
||||||
) -> FlaskResponse:
|
) -> FlaskResponse:
|
||||||
"""Favorite slices for a user"""
|
"""Favorite slices for a user"""
|
||||||
if not user_id:
|
if not user_id:
|
||||||
user_id = g.user.id
|
user_id = g.user.get_id()
|
||||||
qry = (
|
qry = (
|
||||||
db.session.query(Slice, FavStar.dttm)
|
db.session.query(Slice, FavStar.dttm)
|
||||||
.join(
|
.join(
|
||||||
|
@ -1779,8 +1783,9 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
||||||
|
|
||||||
edit_perm = is_owner(dash, g.user) or admin_role in get_user_roles()
|
edit_perm = is_owner(dash, g.user) or admin_role in get_user_roles()
|
||||||
if not edit_perm:
|
if not edit_perm:
|
||||||
|
username = g.user.username if hasattr(g.user, "username") else "user"
|
||||||
return json_error_response(
|
return json_error_response(
|
||||||
f'ERROR: "{g.user.username}" cannot alter '
|
f'ERROR: "{username}" cannot alter '
|
||||||
f'dashboard "{dash.dashboard_title}"',
|
f'dashboard "{dash.dashboard_title}"',
|
||||||
status=403,
|
status=403,
|
||||||
)
|
)
|
||||||
|
@ -2304,7 +2309,9 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
||||||
rendered_query,
|
rendered_query,
|
||||||
return_results=False,
|
return_results=False,
|
||||||
store_results=not query.select_as_cta,
|
store_results=not query.select_as_cta,
|
||||||
user_name=g.user.username if g.user else None,
|
user_name=g.user.username
|
||||||
|
if g.user and hasattr(g.user, "username")
|
||||||
|
else None,
|
||||||
start_time=now_as_float(),
|
start_time=now_as_float(),
|
||||||
expand_data=expand_data,
|
expand_data=expand_data,
|
||||||
log_params=log_params,
|
log_params=log_params,
|
||||||
|
@ -2376,7 +2383,9 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
||||||
rendered_query,
|
rendered_query,
|
||||||
return_results=True,
|
return_results=True,
|
||||||
store_results=store_results,
|
store_results=store_results,
|
||||||
user_name=g.user.username if g.user else None,
|
user_name=g.user.username
|
||||||
|
if g.user and hasattr(g.user, "username")
|
||||||
|
else None,
|
||||||
expand_data=expand_data,
|
expand_data=expand_data,
|
||||||
log_params=log_params,
|
log_params=log_params,
|
||||||
)
|
)
|
||||||
|
|
|
@ -219,7 +219,7 @@ class CsvToDatabaseView(SimpleFormView):
|
||||||
sqla_table = SqlaTable(table_name=csv_table.table)
|
sqla_table = SqlaTable(table_name=csv_table.table)
|
||||||
sqla_table.database = expore_database
|
sqla_table.database = expore_database
|
||||||
sqla_table.database_id = database.id
|
sqla_table.database_id = database.id
|
||||||
sqla_table.user_id = g.user.id
|
sqla_table.user_id = g.user.get_id()
|
||||||
sqla_table.schema = csv_table.schema
|
sqla_table.schema = csv_table.schema
|
||||||
sqla_table.fetch_metadata()
|
sqla_table.fetch_metadata()
|
||||||
db.session.add(sqla_table)
|
db.session.add(sqla_table)
|
||||||
|
@ -360,7 +360,7 @@ class ExcelToDatabaseView(SimpleFormView):
|
||||||
sqla_table = SqlaTable(table_name=excel_table.table)
|
sqla_table = SqlaTable(table_name=excel_table.table)
|
||||||
sqla_table.database = expore_database
|
sqla_table.database = expore_database
|
||||||
sqla_table.database_id = database.id
|
sqla_table.database_id = database.id
|
||||||
sqla_table.user_id = g.user.id
|
sqla_table.user_id = g.user.get_id()
|
||||||
sqla_table.schema = excel_table.schema
|
sqla_table.schema = excel_table.schema
|
||||||
sqla_table.fetch_metadata()
|
sqla_table.fetch_metadata()
|
||||||
db.session.add(sqla_table)
|
db.session.add(sqla_table)
|
||||||
|
|
|
@ -297,4 +297,4 @@ class SqlLab(BaseSupersetView):
|
||||||
@has_access
|
@has_access
|
||||||
def my_queries(self) -> FlaskResponse: # pylint: disable=no-self-use
|
def my_queries(self) -> FlaskResponse: # pylint: disable=no-self-use
|
||||||
"""Assigns a list of found users to the given role."""
|
"""Assigns a list of found users to the given role."""
|
||||||
return redirect("/savedqueryview/list/?_flt_0_user={}".format(g.user.id))
|
return redirect("/savedqueryview/list/?_flt_0_user={}".format(g.user.get_id()))
|
||||||
|
|
Loading…
Reference in New Issue