fix: prevent guest users from changing columns (#29530)

This commit is contained in:
Beto Dealmeida
2024-07-10 12:26:51 -04:00
committed by GitHub
parent 1d35ca4bc5
commit 67df4e3ce3
2 changed files with 186 additions and 30 deletions

View File

@@ -67,7 +67,6 @@ from superset.security.guest_token import (
GuestUser,
)
from superset.sql_parse import extract_tables_from_jinja_sql, Table
from superset.superset_typing import Metric
from superset.utils import json
from superset.utils.core import (
DatasourceName,
@@ -145,11 +144,11 @@ RoleModelView.edit_columns = ["name", "permissions", "user"]
RoleModelView.related_views = []
def freeze_metric(metric: Metric) -> str:
def freeze_value(value: Any) -> str:
"""
Used to compare metric sets.
Used to compare column and metric sets.
"""
return json.dumps(metric, sort_keys=True)
return json.dumps(value, sort_keys=True)
def query_context_modified(query_context: "QueryContext") -> bool:
@@ -170,32 +169,37 @@ def query_context_modified(query_context: "QueryContext") -> bool:
if form_data.get("slice_id") != stored_chart.id:
return True
# compare form_data
requested_metrics = {
freeze_metric(metric) for metric in form_data.get("metrics") or []
}
stored_metrics = {
freeze_metric(metric)
for metric in stored_chart.params_dict.get("metrics") or []
}
if not requested_metrics.issubset(stored_metrics):
return True
stored_query_context = (
json.loads(cast(str, stored_chart.query_context))
if stored_chart.query_context
else None
)
# compare queries in query_context
queries_metrics = {
freeze_metric(metric)
for query in query_context.queries
for metric in query.metrics or []
}
# compare columns and metrics in form_data with stored values
for key in ["metrics", "columns", "groupby"]:
requested_values = {freeze_value(value) for value in form_data.get(key) or []}
stored_values = {
freeze_value(value) for value in stored_chart.params_dict.get(key) or []
}
if not requested_values.issubset(stored_values):
return True
if stored_chart.query_context:
stored_query_context = json.loads(cast(str, stored_chart.query_context))
for query in stored_query_context.get("queries") or []:
stored_metrics.update(
{freeze_metric(metric) for metric in query.get("metrics") or []}
)
# compare queries in query_context
queries_values = {
freeze_value(value)
for query in query_context.queries
for value in getattr(query, key, []) or []
}
if stored_query_context:
for query in stored_query_context.get("queries") or []:
stored_values.update(
{freeze_value(value) for value in query.get(key) or []}
)
return not queries_metrics.issubset(stored_metrics)
if not queries_values.issubset(stored_values):
return True
return False
class SupersetSecurityManager( # pylint: disable=too-many-public-methods